Logo Search packages:      
Sourcecode: jppy version File versions  Download package

pytype_contacts.c

#include <Python.h>
#include <vobject.h>

#include "move_into_libpisock.h"
#include "pytype_contacts.h"
#include "pytype_basics.h"
#include "structmember.h"
#include <pi-buffer.h>

/*******************************************************
 * Create and delloc methods for objects 
 ******************************************************/

extern PyObject* PyPiContact_New(PyTypeObject *type, PyObject *args, PyObject *kwds) {
  int i;
  PyPiContact* self;

  /* Why do we have to do this here? The one in the swig init doesn't seem
     to work ?! */
  mxDateTime_ImportModuleAndAPI();

  ContactType.ob_type = &PyType_Type;
  self = (PyPiContact *)type->tp_alloc(type, 0);
  new_Contact(&(self->a));
  SetBasicRecordObjectAttributeDefaults((PyObject*) self, pack_Contact);  

  return (PyObject*)self;
}

extern int PyPiContact_Init(PyObject *self, PyObject *args, PyObject *kwds) {
  PyPiContact* fromcontact = NULL;
  PyPiContact* contact = NULL;
  int i;
  int malloc_failed = 0;
  
  static char *kwlist[] = {"contact", NULL};
  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, 
                           &fromcontact)) {
    return -1;
  }
  
  contact = (PyPiContact*)self;
  /* we have to support calling __init__ more than once */
  free_Contact(&(contact->a));
  if (contact->saved_br.size > 0 && contact->saved_br.buf) {      
    free(contact->saved_br.buf);                            
  }

  if ((fromcontact == NULL) || ((PyObject *)fromcontact == Py_None)) {
    /* Initialise attributes custom to this type of object */
    new_Contact(&(contact->a));
    SetBasicRecordObjectAttributeDefaults((PyObject*) contact, pack_Contact);    
  } else {
    if (!PyPiContact_Check(fromcontact)) {
      PyErr_SetString(PyExc_TypeError,"Must provide a Contact object to share");
      return -1;
    }
  
    /* copy all the database agnostic record attributes */
    contact->saved_br.size = fromcontact->saved_br.size;
    contact->saved_br.attrib = fromcontact->saved_br.attrib;
    contact->saved_br.rt = fromcontact->saved_br.rt;
    contact->saved_br.unique_id = fromcontact->saved_br.unique_id;

    contact->rt = fromcontact->rt;
    contact->unique_id = fromcontact->unique_id;
    
    contact->saved_br.buf = malloc(fromcontact->saved_br.size);
    memcpy(contact->saved_br.buf,
         fromcontact->saved_br.buf,
         fromcontact->saved_br.size);
    
    contact->category = fromcontact->category;
    contact->unsaved_changes = fromcontact->unsaved_changes;
    contact->deleted = fromcontact->deleted;
    contact->modified = fromcontact->modified;
    contact->busy = fromcontact->busy;
    contact->secret = fromcontact->secret;
    
    /* copy non-pointer data */
    memcpy(&(contact->a), &(fromcontact->a), sizeof(struct Contact));
    
    /* Now do the pointers */
    
    if (fromcontact->a.picture) {
      contact->a.picture = pi_buffer_new((fromcontact->a.picture)->used);
      if (contact->a.picture == NULL) {
      PyErr_SetString(PyExc_MemoryError,"Unable to allocate memory for picture");
      return -1;      
      }
      (contact->a.picture)->used = (fromcontact->a.picture)->used;
      memcpy((contact->a.picture)->data,(fromcontact->a.picture)->data,(fromcontact->a.picture)->used);
    }
    
    for(i=0;i<NUM_CONTACT_ENTRIES;i++) {
      if (fromcontact->a.entry[i]) {
      if ((contact->a.entry[i] = malloc(strlen(fromcontact->a.entry[i])+1)) == NULL) {
        malloc_failed = 1;
      } else {
        strcpy(contact->a.entry[i],fromcontact->a.entry[i]);
      }
      } else {
      contact->a.entry[i] = NULL;
      }
    }
    
    if (malloc_failed) { /* Oh well, undo the mallocs that worked */
      for(i=0;i<NUM_CONTACT_ENTRIES;i++) {
      if (fromcontact->a.entry[i]) {
        free(fromcontact->a.entry[i]);
      }
      }
      PyErr_SetString(PyExc_MemoryError,"Unable to allocate memory for contact entires");
      return -1;
    }
  }

  return 0;
}

static PyObject * PyPiContact_Allocate(PyTypeObject *type, int nitems) {
  PyPiContact *contact;
  if (type == &ContactType) {
    contact = PyObject_New(PyPiContact, &ContactType);
    return (PyObject *) contact;
  } else {
    /* Is this for subclasses ? */
    contact = (PyPiContact *)PyType_GenericAlloc(type, nitems);
    return (PyObject*)contact;
  }
}

extern PyObject* PyPiContact_Wrap(struct Contact *a, PCRecType rt, 
                         unsigned int unique_id, unsigned char attrib,
                         int size, void* buf) {
  PyPiContact* contact;
  int i;
  int malloc_failed = 0;
  
  contact = (PyPiContact*)PyPiContact_New(&ContactType,NULL,NULL);

  /* copy birthday stuff, phoneLabels and showPhone */
  memcpy(&(contact->a), a, sizeof(struct Contact));

  /* set saved_br stuff, and rt and unique_id, and attrib derived details for the current contact */
  SetSavedBrAndRTandUniqueIDandAttribs(rt, unique_id, attrib, size, buf, (PyObject *)contact);

  /* Now do the pointers */
  if (a->picture) {
    contact->a.picture = pi_buffer_new((a->picture)->used);
    if (contact->a.picture == NULL) {
      PyErr_SetString(PyExc_MemoryError,"Unable to allocate memory for picture");
      return NULL;          
    }
    (contact->a.picture)->used = (a->picture)->used;
    memcpy((contact->a.picture)->data,(a->picture)->data,(a->picture)->used);
  }

  for(i=0;i<NUM_CONTACT_ENTRIES;i++) {
    if (a->entry[i]) {
      if ((contact->a.entry[i] = malloc(strlen(a->entry[i])+1)) == NULL) {
      malloc_failed = 1;
      } else {
      strcpy(contact->a.entry[i],a->entry[i]);
      }
    } else {
      contact->a.entry[i] = NULL;
    }
  }

  if (malloc_failed) { /* Oh well, undo the mallocs that worked */
    for(i=0;i<NUM_CONTACT_ENTRIES;i++) {
      if (a->entry[i]) {
      free(a->entry[i]);
      }
    }
    PyErr_SetString(PyExc_MemoryError,"Unable to allocate memory for contact entires");
    return NULL;      
  }

  return (PyObject*)contact;
}

static void PyPiContact_Dealloc(PyPiContact* self) {
  free_Contact(&(self->a));
  if (self->saved_br.size > 0 && self->saved_br.buf) {
    free(self->saved_br.buf);
  }
  self->ob_type->tp_free((PyObject*)self);
}


#define JPPY_CONTACT_SORT_FIELD contLastname
static int PyPiContact_Compare(PyPiContact* self,PyPiContact *other) {
  int res;

  if ((self->a.entry[JPPY_CONTACT_SORT_FIELD]) &&
      (other->a.entry[JPPY_CONTACT_SORT_FIELD])) {
    
    res = strcasecmp(self->a.entry[JPPY_CONTACT_SORT_FIELD],
             other->a.entry[JPPY_CONTACT_SORT_FIELD]);
    if (res > 0) {
      res = 1;
    } else if (res < 0) {
      res = -1;
    } else {
      res = 0;
    }
  } else if (self->a.entry[JPPY_CONTACT_SORT_FIELD]) {
    res = -1;
  } else if (other->a.entry[JPPY_CONTACT_SORT_FIELD]) {
    res = 1;
  } else {
    res = 0;
  }

  return res;

}

static char *PyPiContact_key_list[] = {
  "lastname",
  "firstname",
  "company",
  "title",
  "picture",
  "phone1",
  "phone2",
  "phone3",
  "phone4",
  "phone5",
  "phone6",
  "phone7",
  "address1",
  "city1",
  "state1",
  "zip1",
  "country1",
  "address2",
  "city2",
  "state2",
  "zip2",
  "country2",
  "address3",
  "city3",
  "state3",
  "zip3",
  "country3",
  "custom1",
  "custom2",
  "custom3",
  "custom4",
  "custom5",
  "custom6",
  "custom7",
  "custom8",
  "custom9",
  "website",
  "birthday",
  "reminder",
  "im1",
  "im2",
  "note",
  "currentphone",
  "showphone",
  "type1",
  "type2",
  "type3",
  "type4",
  "type5",
  "type6",
  "type7",
  "typeim1",
  "typeim2",
  "typeaddr1",
  "typeaddr2",
  "typeaddr3",
  "phones",
  "phones_with_labels",
  "email",
  "mobile",
  NULL};

static PyObject* PyPiContact_keys(PyObject* self) {
  PyObject *list = PyList_New(0);
  int n = 0;

  while (PyPiContact_key_list[n]) {
    PyObject *value;
    value = PyString_FromString(PyPiContact_key_list[n++]);
    PyList_Append(list, value);
    Py_DECREF(value);
  }
  return list;
}

PyObject *PyPiContact_GetItem(PyPiContact* self,  PyObject* key);

static PyObject* PyPiContact_values(PyObject* self) {
  PyObject *list = PyList_New(0);
  int n = 0;

  while (PyPiContact_key_list[n]) {
    PyObject *key;
    PyObject *value;
    key   = PyString_FromString(PyPiContact_key_list[n++]);
    value = PyPiContact_GetItem((PyPiContact *)self, key);
    PyList_Append(list, value);
    Py_DECREF(key);
    Py_DECREF(value);
  }
  return list;
}

static PyObject* PyPiContact_items(PyObject* self) {
  PyObject *list = PyList_New(0);
  int n = 0;

  while (PyPiContact_key_list[n]) {
    PyObject *key, *value, *tuple;
    key = PyString_FromString(PyPiContact_key_list[n++]);
    value = PyPiContact_GetItem((PyPiContact *)self, key);
    tuple = Py_BuildValue("(OO)", key, value);
    PyList_Append(list, tuple); /* get it's own ref */
    Py_DECREF(key);
    Py_DECREF(value);
    Py_DECREF(tuple);
  }
  return list;
}


/*******************************************************
 * Delete (from file), save and log methods for the Contact objects
 ******************************************************/

static PyObject* PyPiContact_Log(PyPiContact* self, PyObject *args) {
  char *newnote;
  char *type,*entry,*p;
  time_t tt;

  entry = NULL;

  if (!PyArg_ParseTuple(args, "s|s:log", &type, &entry))
    return NULL;
  
  if(entry==NULL) {
    entry=type;
    type=NULL;
  }
  
  tt = time(NULL);
  p = ctime(&tt);
  if (p[24] == '\n')
    p[24] = '\0';

  if(self->a.entry[contNote] == NULL) {
    self->a.entry[contNote] = malloc(1);
    self->a.entry[contNote][0] = '\0';
  }

  newnote = malloc(32768);
  if ((newnote == NULL) || (self->a.entry[contNote] == NULL)) {
    PyErr_SetString(PyExc_MemoryError,"Unable to allocate memory for new note string");
    return NULL;      
  }

  if(type) 
    snprintf(newnote,32768,"%s\n\n%s\n%s: %s", self->a.entry[contNote], p, type, entry);
  else
    snprintf(newnote,32768,"%s\n\n%s\n%s", self->a.entry[contNote], p, entry);    

  free(self->a.entry[contNote]);
  self->a.entry[contNote] = newnote;

  self->unsaved_changes = 1;
  Py_INCREF(Py_None);
  return Py_None;  
}

/************************
 * vCard generation
 ************************/

static PyObject* PyPiContact_Generate_VCard(PyPiContact* self, PyObject *args, PyObject *kw) {
  VObject *prop;
  VObject *vcard;
  char strbuf[255];
  char* clipboard;
  int i;
  int minimal = 0;

  char *keywords[] = {"minimal", NULL};

  if (!PyArg_ParseTupleAndKeywords(args, kw, "|i:vcard", keywords, &minimal))
    return NULL;  
  
  vcard = newVObject(VCCardProp);

  safeAddPropValue(vcard,VCVersionProp,"2.1");
  snprintf(strbuf, 254, "%d", self->unique_id);
  safeAddPropValue(vcard,VCUniqueStringProp,strbuf);

  if ((self->a.entry[contFirstname]) || (self->a.entry[contLastname])) {
    prop = addProp(vcard,VCNameProp);
    
    safeAddPropValuePart(prop,VCFamilyNameProp,self->a.entry[contLastname]);
    safeAddPropValuePart(prop,VCGivenNameProp,self->a.entry[contFirstname]);
    
    if ((self->a.entry[contFirstname]) && (self->a.entry[contLastname])) {
      snprintf(strbuf,254,"%s %s", self->a.entry[contFirstname], self->a.entry[contLastname]);
      safeAddPropValue(vcard,VCFullNameProp,strbuf);
    } else if (self->a.entry[contFirstname]) {
      safeAddPropValue(vcard,VCFullNameProp,self->a.entry[contFirstname]);
    }  else if (self->a.entry[contLastname]) {
      safeAddPropValue(vcard,VCFullNameProp,self->a.entry[contLastname]);
    }
  }
  
  if (self->a.entry[contCompany] && strcmp("",self->a.entry[contCompany])) {
    prop = addProp(vcard,VCOrgProp);
    safeAddPropValue(prop,VCOrgNameProp,self->a.entry[contCompany]);
  }

  safeAddPropValue(vcard,VCTitleProp,self->a.entry[contTitle]);

  for (i=0;i<NUM_CONTACT_PHONES;i++) {
    if ((self->a.entry[contPhone1 + i]) && (strcmp("",self->a.entry[contPhone1 + i]))) {
      switch(self->a.phoneLabel[i]) {
      case 0:
      prop = safeAddPropValue(vcard,VCTelephoneProp,self->a.entry[contPhone1 + i]);
      addProp(prop,VCWorkProp);
      continue;
      case 1:
      prop = safeAddPropValue(vcard,VCTelephoneProp,self->a.entry[contPhone1 + i]);
      addProp(prop,VCHomeProp);
      continue;
      case 2:
      prop = safeAddPropValue(vcard,VCTelephoneProp,self->a.entry[contPhone1 + i]);
      addProp(prop,VCFaxProp);
      continue;
      case 3:
      safeAddPropValue(vcard,VCTelephoneProp,self->a.entry[contPhone1 + i]); /* other ? */
      continue;
      case 4:
      prop = safeAddPropValue(vcard,VCEmailAddressProp,self->a.entry[contPhone1 + i]);
      addProp(prop,VCInternetProp);
      continue;
      case 5:
      safeAddPropValue(vcard,VCTelephoneProp,self->a.entry[contPhone1 + i]); /* main */
      continue;
      case 6:
      prop = safeAddPropValue(vcard,VCTelephoneProp,self->a.entry[contPhone1 + i]);
      addProp(prop,VCPagerProp);
      continue;
      case 7:
      prop = safeAddPropValue(vcard,VCTelephoneProp,self->a.entry[contPhone1 + i]);
      addProp(prop,VCCellularProp);
      continue;
      }
    }
  }

  if (!minimal) {
    if (self->a.entry[contIM1]    && strcmp("",self->a.entry[contIM1])) {
      switch (self->a.IMLabel[0]) {
      case 0: 
      safeAddPropValue(vcard,"X-AIM",self->a.entry[contIM1]);
      break;
      case 1: 
      safeAddPropValue(vcard,"X-MSN",self->a.entry[contIM1]);    
      break;
      case 2: 
      safeAddPropValue(vcard,"X-YAHOO",self->a.entry[contIM1]);    
      break;
      case 3: 
      safeAddPropValue(vcard,"X-ICQ",self->a.entry[contIM1]);    
      break;
      case 4: 
      safeAddPropValue(vcard,"X-IM",self->a.entry[contIM1]);    
      break;
      }
    }
    if (self->a.entry[contIM2]    && strcmp("",self->a.entry[contIM2])) {
      switch (self->a.IMLabel[1]) {
      case 0: 
      safeAddPropValue(vcard,"X-AIM",self->a.entry[contIM2]);    
      break;
      case 1: 
      safeAddPropValue(vcard,"X-MSN",self->a.entry[contIM2]);    
      break;
      case 2: 
      safeAddPropValue(vcard,"X-YAHOO",self->a.entry[contIM2]);    
      break;
      case 3: 
      safeAddPropValue(vcard,"X-ICQ",self->a.entry[contIM2]);    
      break;
      case 4: 
      safeAddPropValue(vcard,"X-IM",self->a.entry[contIM2]);    
      break;
      }
    }
  }
  
  if (!minimal) {
    char date_string[9];
    if (self->a.birthdayFlag) {
      snprintf(date_string,
             9,
             "%04d%02d%02d", 
             self->a.birthday.tm_year + 1900, 
             self->a.birthday.tm_mon + 1, 
             self->a.birthday.tm_mday);
      safeAddPropValue(vcard,VCBirthDateProp,date_string);
    }

    safeAddPropValue(vcard,VCCommentProp,self->a.entry[contNote]);

    if (self->a.pictype == cpic_jpeg) {
      prop = addProp(vcard,VCPhotoProp);
      setValueWithSize(prop, 
                   (self->a.picture)->data, 
                   (self->a.picture)->used);
      addPropValue(prop,"TYPE",VCJPEGProp);
      addPropValue(prop,VCEncodingProp,VCBase64Prop);
    }
  
#define PYTYPE_CONTACTS_ADD_ADR_TO_VCARD(NUM) \
    if ((self->a.entry[contAddress##NUM] && strcmp("",self->a.entry[contAddress##NUM])) || \
      (self->a.entry[contCity##NUM]    && strcmp("",self->a.entry[contCity##NUM])) || \
      (self->a.entry[contState##NUM]   && strcmp("",self->a.entry[contState##NUM])) || \
      (self->a.entry[contZip##NUM]     && strcmp("",self->a.entry[contZip##NUM])) || \
      (self->a.entry[contCountry##NUM] && strcmp("",self->a.entry[contCountry##NUM]))) { \
      prop = addProp(vcard, VCAdrProp); \
      switch(self->a.addressLabel[0]) { \
      case 0: addProp(prop,VCWorkProp); break; \
      case 1: addProp(prop,VCHomeProp); break; \
      } \
      safeAddPropValuePart(prop, VCStreetAddressProp, self->a.entry[contAddress##NUM]); \
      safeAddPropValuePart(prop, VCCityProp, self->a.entry[contCity##NUM]); \
      safeAddPropValuePart(prop, VCRegionProp, self->a.entry[contState##NUM]); \
      safeAddPropValuePart(prop, VCPostalCodeProp, self->a.entry[contZip##NUM]); \
      safeAddPropValuePart(prop, VCCountryNameProp, self->a.entry[contCountry##NUM]); \
    };

    PYTYPE_CONTACTS_ADD_ADR_TO_VCARD(1);
    PYTYPE_CONTACTS_ADD_ADR_TO_VCARD(2);
    PYTYPE_CONTACTS_ADD_ADR_TO_VCARD(3);

    for (i=0;i<NUM_CONTACT_CUSTOMS;i++) {  
      if (self->a.entry[contCustom1 + i]){
      snprintf(strbuf,20,"X-Palm-Custom%d",i + 1);
      safeAddPropValue(vcard,strbuf,self->a.entry[contCustom1 + i]);
      }
    }
  }
  clipboard = writeMemVObject(0,0,vcard);
  return PyString_FromString(clipboard);
}



static PyMethodDef PyPiContact_Methods[] = {
  { "log",  (PyCFunction)PyPiContact_Log,    METH_VARARGS, "Make a log entry"},
  { "vcard",(PyCFunction)PyPiContact_Generate_VCard, METH_KEYWORDS, "Generate a vcard"},
  { "keys", (PyCFunction)PyPiContact_keys, METH_NOARGS, "Return a list of available keys"},
  { "items",(PyCFunction)PyPiContact_items, METH_NOARGS, "Return a list of available items"},
  { "values",(PyCFunction)PyPiContact_values, METH_NOARGS, "Return a list of available items"},
  {NULL,NULL}
};


static PyMemberDef PyPiContact_Members[] = {
  PYPI_MEMBERS_HEAD,
  {NULL}  /* Sentinel */
};

static PyGetSetDef PyPiContact_Getseters[] = {
  PYPI_GETSETERS_HEAD,
  {NULL}  /* Sentinel */
};

/**** mapping interface ****/
int PyPiContact_Len(self) {
  return 5;
}


PyObject *PyPiContact_GetItem(PyPiContact* self,  PyObject* key) {
  char *keystring;
  PyObject* py_list;
  int n, i;

  if (!PyString_Check(key)) {
    Py_INCREF(Py_None);
    return Py_None;  
  }

  Py_INCREF(key);
  keystring = PyString_AsString(key);

  GET_STRING_ATTR(keystring,"lastname", a.entry[contLastname]);
  GET_STRING_ATTR(keystring,"firstname", a.entry[contFirstname]);
  GET_STRING_ATTR(keystring,"company", a.entry[contCompany]);
  GET_STRING_ATTR(keystring,"title", a.entry[contTitle]);

  GET_STRING_ATTR(keystring,"phone1", a.entry[contPhone1]);
  GET_STRING_ATTR(keystring,"phone2", a.entry[contPhone2]);
  GET_STRING_ATTR(keystring,"phone3", a.entry[contPhone3]);
  GET_STRING_ATTR(keystring,"phone4", a.entry[contPhone4]);
  GET_STRING_ATTR(keystring,"phone5", a.entry[contPhone5]);
  GET_STRING_ATTR(keystring,"phone6", a.entry[contPhone6]);
  GET_STRING_ATTR(keystring,"phone7", a.entry[contPhone7]);

  GET_STRING_ATTR(keystring,"address1", a.entry[contAddress1]);
  GET_STRING_ATTR(keystring,"city1", a.entry[contCity1]);
  GET_STRING_ATTR(keystring,"state1", a.entry[contState1]);
  GET_STRING_ATTR(keystring,"zip1", a.entry[contZip1]);
  GET_STRING_ATTR(keystring,"country1", a.entry[contCountry1]);
  
  GET_STRING_ATTR(keystring,"address2", a.entry[contAddress2]);
  GET_STRING_ATTR(keystring,"city2", a.entry[contCity2]);
  GET_STRING_ATTR(keystring,"state2", a.entry[contState2]);
  GET_STRING_ATTR(keystring,"zip2", a.entry[contZip2]);
  GET_STRING_ATTR(keystring,"country2", a.entry[contCountry2]);

  GET_STRING_ATTR(keystring,"address3", a.entry[contAddress3]);
  GET_STRING_ATTR(keystring,"city3", a.entry[contCity3]);
  GET_STRING_ATTR(keystring,"state3", a.entry[contState3]);
  GET_STRING_ATTR(keystring,"zip3", a.entry[contZip3]);
  GET_STRING_ATTR(keystring,"country3", a.entry[contCountry3]);

  GET_STRING_ATTR(keystring,"custom1", a.entry[contCustom1]);
  GET_STRING_ATTR(keystring,"custom2", a.entry[contCustom2]);
  GET_STRING_ATTR(keystring,"custom3", a.entry[contCustom3]);
  GET_STRING_ATTR(keystring,"custom4", a.entry[contCustom4]);
  GET_STRING_ATTR(keystring,"custom5", a.entry[contCustom5]);
  GET_STRING_ATTR(keystring,"custom6", a.entry[contCustom6]);
  GET_STRING_ATTR(keystring,"custom7", a.entry[contCustom7]);
  GET_STRING_ATTR(keystring,"custom8", a.entry[contCustom8]);
  GET_STRING_ATTR(keystring,"custom9", a.entry[contCustom9]);

  GET_STRING_ATTR(keystring,"website",a.entry[contWebsite]);

  GET_DATE_AND_INVERSE_FLAG_ATTR(keystring,"birthday",a.birthday,a.birthdayFlag);
  GET_INT_OR_NONE_ATTR(keystring,"reminder",a.reminder);

  GET_STRING_ATTR(keystring,"im1",a.entry[contIM1]);
  GET_STRING_ATTR(keystring,"im2",a.entry[contIM2]);

  GET_STRING_ATTR(keystring,"note", a.entry[contNote]);

  GET_STRING_ATTR(keystring,"currentphone",a.entry[self->a.showPhone+contPhone1]);
  GET_INT_ATTR(keystring,"showphone",a.showPhone);

  GET_INT_ATTR(keystring,"type1",a.phoneLabel[0]);
  GET_INT_ATTR(keystring,"type2",a.phoneLabel[1]);
  GET_INT_ATTR(keystring,"type3",a.phoneLabel[2]);
  GET_INT_ATTR(keystring,"type4",a.phoneLabel[3]);
  GET_INT_ATTR(keystring,"type5",a.phoneLabel[4]);
  GET_INT_ATTR(keystring,"type6",a.phoneLabel[5]);
  GET_INT_ATTR(keystring,"type7",a.phoneLabel[6]);

  GET_INT_ATTR(keystring,"typeim1",a.IMLabel[0]);
  GET_INT_ATTR(keystring,"typeim2",a.IMLabel[1]);

  GET_INT_ATTR(keystring,"typeaddr1",a.addressLabel[0]);
  GET_INT_ATTR(keystring,"typeaddr2",a.addressLabel[1]);
  GET_INT_ATTR(keystring,"typeaddr3",a.addressLabel[2]);

  if (strcasecmp(keystring,"picture") == 0) {
    if ((self->a.pictype == cpic_jpeg) && (self->a.picture)) {
      PyObject *value;
      value = PyString_FromStringAndSize((char *)((self->a.picture)->data), (self->a.picture)->used);
      Py_DECREF(key);
      return value;
    } else {
      Py_DECREF(key);
      Py_INCREF(Py_None);
      return Py_None;
    }
  }

  if (strcasecmp(keystring,"phones") == 0) {
    py_list = PyList_New(NUM_CONTACT_PHONES);
    PyList_SET_ITEM(py_list, 0, PyPiContact_GetItem(self, PyString_FromString("phone1")));
    PyList_SET_ITEM(py_list, 1, PyPiContact_GetItem(self, PyString_FromString("phone2")));
    PyList_SET_ITEM(py_list, 2, PyPiContact_GetItem(self, PyString_FromString("phone3")));
    PyList_SET_ITEM(py_list, 3, PyPiContact_GetItem(self, PyString_FromString("phone4")));
    PyList_SET_ITEM(py_list, 4, PyPiContact_GetItem(self, PyString_FromString("phone5")));
    PyList_SET_ITEM(py_list, 5, PyPiContact_GetItem(self, PyString_FromString("phone6")));
    PyList_SET_ITEM(py_list, 6, PyPiContact_GetItem(self, PyString_FromString("phone7")));
    Py_DECREF(key);
    return py_list;
  }  

  if (strcasecmp(keystring,"phones_with_labels") == 0) {
    py_list = PyList_New(NUM_CONTACT_PHONES);
    PyList_SET_ITEM(py_list, 0, Py_BuildValue("(Oi)",PyPiContact_GetItem(self, PyString_FromString("phone1")),
                                    self->a.phoneLabel[0]));
    PyList_SET_ITEM(py_list, 1, Py_BuildValue("(Oi)",PyPiContact_GetItem(self, PyString_FromString("phone2")),
                                    self->a.phoneLabel[1]));
    PyList_SET_ITEM(py_list, 2, Py_BuildValue("(Oi)",PyPiContact_GetItem(self, PyString_FromString("phone3")),
                                    self->a.phoneLabel[2]));
    PyList_SET_ITEM(py_list, 3, Py_BuildValue("(Oi)",PyPiContact_GetItem(self, PyString_FromString("phone4")),
                                    self->a.phoneLabel[3]));
    PyList_SET_ITEM(py_list, 4, Py_BuildValue("(Oi)",PyPiContact_GetItem(self, PyString_FromString("phone5")),
                                    self->a.phoneLabel[4]));
    PyList_SET_ITEM(py_list, 5, Py_BuildValue("(Oi)",PyPiContact_GetItem(self, PyString_FromString("phone6")),
                                    self->a.phoneLabel[5]));
    PyList_SET_ITEM(py_list, 6, Py_BuildValue("(Oi)",PyPiContact_GetItem(self, PyString_FromString("phone7")),
                                    self->a.phoneLabel[6]));
    Py_DECREF(key);
    return py_list;
  } 

  n = -1;
  if (strcasecmp(keystring,"email") == 0) {
    n = 4;
  } else if (strcasecmp(keystring,"mobile") == 0) {
    n = 7;
  }
  if (n > 0) {
    for(i=0;i<NUM_CONTACT_PHONES;i++) {
      if (n == self->a.phoneLabel[i]) {
      if (self->a.entry[contPhone1 + i] != NULL) {
        Py_DECREF(key);
        return PyString_FromString(self->a.entry[contPhone1 + i]);
      }
      }
    }
    Py_DECREF(key);
    Py_INCREF(Py_None);
    return Py_None;  
  }
  
  PyErr_Format(PyExc_KeyError,"no such key '%s'", keystring);
  Py_DECREF(key);
  return NULL;
}

int PyPiContact_SetItem(PyPiContact* self, PyObject* key, PyObject* value) {
  char buf[255];
  char *keystring;
  PyObject *pytup, *pyint, *pystr;
  int n;

  if (!PyString_Check(key)) {
    PyErr_SetString(PyExc_TypeError,"key must be a String");
    return -1;
  }
  
  Py_INCREF(key);
  keystring = PyString_AsString(key);

  if (value == NULL) {
    PyErr_Format(PyExc_ValueError,"Can't delete value %s", keystring);
    return -1;
  }
  
  SET_STRING_ATTR(keystring,"lastname",a.entry[contLastname],value, 4096); 
  SET_STRING_ATTR(keystring,"firstname",a.entry[contFirstname],value, 4096);
  SET_STRING_ATTR(keystring,"company",a.entry[contCompany],value, 4096);
  SET_STRING_ATTR(keystring,"title",a.entry[contTitle],value, 4096);

  SET_STRING_ATTR(keystring,"phone1",a.entry[contPhone1],value, 4096);
  SET_STRING_ATTR(keystring,"phone2",a.entry[contPhone2],value, 4096);
  SET_STRING_ATTR(keystring,"phone3",a.entry[contPhone3],value, 4096);
  SET_STRING_ATTR(keystring,"phone4",a.entry[contPhone4],value, 4096);
  SET_STRING_ATTR(keystring,"phone5",a.entry[contPhone5],value, 4096);
  SET_STRING_ATTR(keystring,"phone6",a.entry[contPhone6],value, 4096);
  SET_STRING_ATTR(keystring,"phone7",a.entry[contPhone7],value, 4096);

  SET_STRING_ATTR(keystring,"address1",a.entry[contAddress1],value, 4096);
  SET_STRING_ATTR(keystring,"city1",a.entry[contCity1],value, 4096);
  SET_STRING_ATTR(keystring,"state1",a.entry[contState1],value, 4096);
  SET_STRING_ATTR(keystring,"zip1",a.entry[contZip1],value, 4096);
  SET_STRING_ATTR(keystring,"country1",a.entry[contCountry1],value, 4096);

  SET_STRING_ATTR(keystring,"address2",a.entry[contAddress2],value, 4096);
  SET_STRING_ATTR(keystring,"city2",a.entry[contCity2],value, 4096);
  SET_STRING_ATTR(keystring,"state2",a.entry[contState2],value, 4096);
  SET_STRING_ATTR(keystring,"zip2",a.entry[contZip2],value, 4096);
  SET_STRING_ATTR(keystring,"country2",a.entry[contCountry2],value, 4096);

  SET_STRING_ATTR(keystring,"address3",a.entry[contAddress3],value, 4096);
  SET_STRING_ATTR(keystring,"city3",a.entry[contCity3],value, 4096);
  SET_STRING_ATTR(keystring,"state3",a.entry[contState3],value, 4096);
  SET_STRING_ATTR(keystring,"zip3",a.entry[contZip3],value, 4096);
  SET_STRING_ATTR(keystring,"country3",a.entry[contCountry3],value, 4096);


  SET_STRING_ATTR(keystring,"custom1",a.entry[contCustom1],value, 4096);
  SET_STRING_ATTR(keystring,"custom2",a.entry[contCustom2],value, 4096);
  SET_STRING_ATTR(keystring,"custom3",a.entry[contCustom3],value, 4096);
  SET_STRING_ATTR(keystring,"custom4",a.entry[contCustom4],value, 4096);
  SET_STRING_ATTR(keystring,"custom5",a.entry[contCustom5],value, 4096);
  SET_STRING_ATTR(keystring,"custom6",a.entry[contCustom6],value, 4096);
  SET_STRING_ATTR(keystring,"custom7",a.entry[contCustom7],value, 4096);
  SET_STRING_ATTR(keystring,"custom8",a.entry[contCustom8],value, 4096);
  SET_STRING_ATTR(keystring,"custom9",a.entry[contCustom9],value, 4096);

  SET_STRING_ATTR(keystring,"website",a.entry[contWebsite],value, 4096);

  SET_DATE_AND_INVERSE_FLAG_ATTR(keystring,"birthday",a.birthday,a.birthdayFlag,value);
  SET_BOUNDED_INT_OR_NONE_ATTR(keystring,"reminder",a.reminder,value,0,99,buf,255);

  SET_STRING_ATTR(keystring,"im1",a.entry[contIM1],value, 4096);
  SET_STRING_ATTR(keystring,"im2",a.entry[contIM2],value, 4096);

  SET_STRING_ATTR(keystring,"note",a.entry[contNote],value, 32768);
  SET_STRING_ATTR(keystring,"currentphone",a.entry[self->a.showPhone+contPhone1],value, 4096);

  SET_BOUNDED_INT_ATTR(keystring,"type1",a.phoneLabel[0],value,0,7,buf,255);
  SET_BOUNDED_INT_ATTR(keystring,"type2",a.phoneLabel[1],value,0,7,buf,255);
  SET_BOUNDED_INT_ATTR(keystring,"type3",a.phoneLabel[2],value,0,7,buf,255);
  SET_BOUNDED_INT_ATTR(keystring,"type4",a.phoneLabel[3],value,0,7,buf,255);
  SET_BOUNDED_INT_ATTR(keystring,"type5",a.phoneLabel[4],value,0,7,buf,255);
  SET_BOUNDED_INT_ATTR(keystring,"type6",a.phoneLabel[5],value,0,7,buf,255);
  SET_BOUNDED_INT_ATTR(keystring,"type7",a.phoneLabel[6],value,0,7,buf,255);

  SET_BOUNDED_INT_ATTR(keystring,"typeim1",a.IMLabel[0],value,0,4,buf,255);
  SET_BOUNDED_INT_ATTR(keystring,"typeim2",a.IMLabel[1],value,0,4,buf,255);

  SET_BOUNDED_INT_ATTR(keystring,"typeaddr1",a.addressLabel[0],value,0,2,buf,255);
  SET_BOUNDED_INT_ATTR(keystring,"typeaddr2",a.addressLabel[1],value,0,2,buf,255);
  SET_BOUNDED_INT_ATTR(keystring,"typeaddr3",a.addressLabel[2],value,0,2,buf,255);

  SET_BOUNDED_INT_ATTR(keystring,"showphone",a.showPhone,value,0,4,buf,255);

  if (strcasecmp(keystring,"picture") == 0) {
    if (value == Py_None) {
      if (self->a.picture) {
      pi_buffer_free(self->a.picture);
      }
      self->a.picture = NULL;
      self->a.pictype = cpic_none;
      Py_DECREF(key);
      return 0;
    }
    if (!PyString_Check(value)) {
      PyErr_SetString(PyExc_TypeError,"picture must be set to a string (jpeg data)");
      Py_DECREF(key);
      return -1;
    }
    int length;
    char *buffer;
    pi_buffer_t *pibuffer;
    PyString_AsStringAndSize(value, &buffer, &length);
    pibuffer = pi_buffer_new(length);
    if (pibuffer == NULL) {
      PyErr_SetString(PyExc_MemoryError,"Unable to allocate memory for picture");
      return -1;      
    }
    if (self->a.picture) {
      pi_buffer_free(self->a.picture);
    }
    self->a.picture = pibuffer;
    (self->a.picture)->used = length;
    memcpy((self->a.picture)->data,buffer,length);
    self->a.pictype = cpic_jpeg;
    self->unsaved_changes = 1;
    Py_DECREF(key);
    return 0;
  }

  if (strcasecmp(keystring,"phones_with_labels") == 0) {
    if (!PyList_Check(value)) {
      PyErr_SetString(PyExc_TypeError,"phone_with_labels must be set to a list");
      Py_DECREF(key);
      return -1;
    }
    if (PyList_GET_SIZE(value) != NUM_CONTACT_PHONES) {
      PyErr_SetString(PyExc_IndexError,"phone_with_labels must have 7 elements");
      Py_DECREF(key);
      return -1;
    }

    for (n=0;n<NUM_CONTACT_PHONES;n++) {
      pytup = PyList_GET_ITEM(value,n);
      if (!PyTuple_Check(pytup)) {
      PyErr_SetString(PyExc_TypeError,"phone_with_labels must be set to a list containing tuples");
      Py_DECREF(key);
      return -1;
      }
      if (PyTuple_Size(pytup) != 2) {
      PyErr_SetString(PyExc_IndexError,"phone_with_labels' tuples must contain two elements");
      Py_DECREF(key);
      return -1;
      }      
      pystr = PyTuple_GET_ITEM(pytup,0);
      pyint = PyTuple_GET_ITEM(pytup,1);
      if (!PyInt_Check(pyint) || !PyString_Check(pystr) || 
        (PyInt_AS_LONG(pyint) > 7 || PyInt_AS_LONG(pyint) < 0)) {
      PyErr_SetString(PyExc_TypeError,
                  "phone_with_labels' tuples must be (string, int) where int 0<=x<=7");
      Py_DECREF(key);
      return -1;
      }
      self->a.entry[contPhone1+n] = realloc(self->a.entry[contPhone1+n],
                                   strlen(PyString_AS_STRING(pystr))+1);
      if(self->a.entry[contPhone1+n] != NULL) {
      strcpy(self->a.entry[contPhone1+n],PyString_AS_STRING(pystr));
      self->a.phoneLabel[n] = PyInt_AS_LONG(pyint);
      self->unsaved_changes = 1;
      } else {
      PyErr_SetString(PyExc_MemoryError,
                  "Unable to save attribute, out of memory (realloc failed)!");
      Py_DECREF(key);
      return -1;
      };
      
    }
    Py_DECREF(key);
    return 0;
  }

  PyErr_SetString(PyExc_KeyError,"no such key");
  Py_DECREF(key);
  return -1;
}

static PyMappingMethods PyPiContact_Mapping = {
  (inquiry)PyPiContact_Len,
  (binaryfunc)PyPiContact_GetItem, 
  (objobjargproc)PyPiContact_SetItem,
};



/*******************************************************
 * Provide a repr method
 ******************************************************/

static PyObject *PyPiContact_Repr(PyPiContact* self) {
  static PyObject *format = NULL;
  PyObject *attrib, *args, *result;
  int len1, len2;

  if (format == NULL) {
    format = PyString_FromString("<%s %r %r %s>");
    if (format == NULL)
      return NULL;
  }
  
  if (self->a.entry[contFirstname]) {
    len1 = strlen(self->a.entry[contFirstname]) > 25 ? 25 : strlen(self->a.entry[contFirstname]);
  } else {
    len1 = 0;
  }

  if (self->a.entry[contLastname]) {
    len2 = strlen(self->a.entry[contLastname]) > 25 ? 25 : strlen(self->a.entry[contLastname]);
  } else {
    len2 = 0;
  }

  args = Py_BuildValue("ss#s#O", 
                   (self->ob_type)->tp_name,
                   self->a.entry[contFirstname],
                   len1,
                   self->a.entry[contLastname],
                   len2,
                   Attribute_Repr((PyObject *)self));

  if (args == NULL)
    return NULL;

  result = PyString_Format(format, args);
  Py_DECREF(args);
  return result;
}


/*******************************************************
 * Declare the type
 ******************************************************/


PyTypeObject ContactType = {
  PyObject_HEAD_INIT(NULL)
  0,
  "jppy._jpilot.__jpilot.Contact",
  sizeof(PyPiContact),
  0,
  (destructor)PyPiContact_Dealloc,      /*tp_dealloc*/
  0,                                /*tp_print*/
  0, /*tp_getattr*/
  0, /*tp_setattr*/
  (cmpfunc)PyPiContact_Compare,     /*tp_compare*/
  (reprfunc)PyPiContact_Repr,       /*tp_repr*/
  0,                                /*tp_as_number*/
  0,                                /*tp_as_sequence*/
  &PyPiContact_Mapping,                                /*tp_as_mapping*/
  0,                                /*tp_hash */
  0,                         /*tp_call*/
  0,                         /*tp_str*/
  0,                         /*tp_getattro*/
  0,                         /*tp_setattro*/
  0,                         /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
  "Contact objects",           /* tp_doc */
  0,                       /* tp_traverse */
  0,                       /* tp_clear */
  0,                       /* tp_richcompare */
  0,                       /* tp_weaklistoffset */
  0,                       /* tp_iter */
  0,                       /* tp_iternext */
  PyPiContact_Methods,             /* tp_methods */
  PyPiContact_Members,            /* tp_members */
  PyPiContact_Getseters,          /* tp_getset */
  0,                         /* tp_base */
  0,                         /* tp_dict */
  0,                         /* tp_descr_get */
  0,                         /* tp_descr_set */
  0,                         /* tp_dictoffset */
  (initproc)PyPiContact_Init,      /* tp_init */
  (allocfunc)PyPiContact_Allocate,                 /* tp_alloc */
  (newfunc)PyPiContact_New,                 /* tp_new */
  0, /* Low-level free-memory routine */
};

Generated by  Doxygen 1.6.0   Back to index