Exemplo n.º 1
0
def createBlogTypePosts():
    blogTypePostService = entityFor(IBlogTypePostService)
    assert isinstance(blogTypePostService, IBlogTypePostService)
    for data in BLOG_TYPE_POSTS:
        pst = Post()
        blogType, pst.Type, creator, author, pst.Content = data
        blogTypeId = getBlogTypesIds()[blogType]
        exists = False
        for post in blogTypePostService.getAll(blogTypeId):
            if post.Content == pst.Content:
                exists = True
                break
        if not exists:
            pst.Creator = getUsersIds()[creator]
            if author: pst.Author = getCollaboratorsIds()[author]
            blogTypePostService.insert(blogTypeId, pst)
Exemplo n.º 2
0
def createBlogPosts():
    blogPostService = entityFor(IBlogPostService)
    assert isinstance(blogPostService, IBlogPostService)
    for _blogName, blogId in _cache_blogs.items():
        if len(blogPostService.getPublished(blogId)) > 0: return
    for data in POSTS:
        pst = Post()
        blog, pst.Type, creator, author, pst.Content = data
        pst.Creator = getUsersIds()[creator]
        if author: pst.Author = getCollaboratorsIds()[author]

        createPostType(pst.Type)
        if pst.Type == 'advertisement':
            blogPostService.insert(getBlogsIds()[blog], pst)
            pst.Id = None
        blogPostService.insertAndPublish(getBlogsIds()[blog], pst)
Exemplo n.º 3
0
def createBlogTypePosts():
    blogTypePostService = entityFor(IBlogTypePostService)
    assert isinstance(blogTypePostService, IBlogTypePostService)
    for data in BLOG_TYPE_POSTS:
        pst = Post()
        blogType, pst.Type, creator, author, pst.Content = data
        blogTypeId = getBlogTypesIds()[blogType]
        exists = False
        for post in blogTypePostService.getAll(blogTypeId):
            if post.Content == pst.Content:
                exists = True
                break
        if not exists:
            pst.Creator = getUsersIds()[creator]
            if author:
                pst.Author = getCollaboratorsIds()[author]
            blogTypePostService.insert(blogTypeId, pst)
Exemplo n.º 4
0
def createBlogPosts():
    blogPostService = entityFor(IBlogPostService)
    assert isinstance(blogPostService, IBlogPostService)
    for _blogName, blogId in getBlogsIds().items():
        published = blogPostService.getPublished(blogId, detailed=True, limit=0)
        assert isinstance(published, IterPart), 'Invalid part %s' % published
        if published.total > 0: return
    for data in defaultPosts():
        pst = Post()
        blog, pst.Type, creator, author, pst.Content = data
        pst.Creator = getUsersIds()[creator]
        if author: pst.Author = getCollaboratorsIds()[author]

        createPostType(pst.Type)
        if pst.Type == 'advertisement':
            blogPostService.insert(getBlogsIds()[blog], pst)
            pst.Id = None
        blogPostService.insertAndPublish(getBlogsIds()[blog], pst)
Exemplo n.º 5
0
def createBlogPosts():
    blogPostService = entityFor(IBlogPostService)
    assert isinstance(blogPostService, IBlogPostService)
    for _blogName, blogId in getBlogsIds().items():
        published = blogPostService.getPublished(blogId, detailed=True, limit=0)
        assert isinstance(published, IterPart), 'Invalid part %s' % published
        if published.total > 0: return
    for data in defaultPosts():
        pst = Post()
        blog, pst.Type, creator, author, pst.Content = data
        pst.Creator = getUsersIds()[creator]
        if author: pst.Author = getCollaboratorsIds()[author]

        createPostType(pst.Type)
        if pst.Type == 'advertisement':
            blogPostService.insert(getBlogsIds()[blog], pst)
            pst.Id = None
        blogPostService.insertAndPublish(getBlogsIds()[blog], pst)
Exemplo n.º 6
0
    def _syncChain(self, blogSync):
        '''
        Synchronize the blog for the given sync entry.

        @param blogSync: BlogSync
            The blog sync entry declaring the blog and source from which the blog
            has to be updated.
        '''
        assert isinstance(blogSync,
                          BlogSync), 'Invalid blog sync %s' % blogSync
        source = self.sourceService.getById(blogSync.Source)

        log.info('_syncChain blogId=%d, sourceId=%d', blogSync.Blog,
                 blogSync.Source)

        assert isinstance(source, Source)
        (scheme, netloc, path, params, query, fragment) = urlparse(source.URI)

        if not scheme: scheme = 'http'

        q = parse_qsl(query, keep_blank_values=True)
        q.append(('asc', 'cId'))
        q.append(
            ('cId.since', blogSync.CId if blogSync.CId is not None else 0))

        url = urlunparse(
            (scheme, netloc, path + '/' + self.published_posts_path, params,
             urlencode(q), fragment))
        req = Request(url,
                      headers={
                          'Accept': self.acceptType,
                          'Accept-Charset': self.encodingType,
                          'X-Filter':
                          '*,Creator.*,Author.User.*,Author.Source.*',
                          'User-Agent': 'Magic Browser'
                      })

        try:
            resp = urlopen(req)
        except (HTTPError, socket.error) as e:
            log.error('Read error on %s: %s' % (source.URI, e))
            blogSync.LastActivity = None
            self.blogSyncService.update(blogSync)
            return

        if str(resp.status) != '200':
            log.error('Read problem on %s, status: %s' %
                      (source.URI, resp.status))
            blogSync.LastActivity = None
            self.blogSyncService.update(blogSync)
            return

        try:
            msg = json.load(codecs.getreader(self.encodingType)(resp))
        except ValueError as e:
            log.error('Invalid JSON data %s' % e)
            blogSync.LastActivity = None
            self.blogSyncService.update(blogSync)
            return

        usersForIcons = {}
        for post in msg['PostList']:
            try:
                if post['IsPublished'] != 'True': continue

                insert = False
                if 'Uuid' in post:
                    uuid = post['Uuid']
                    localPost = self.postService.getByUuidAndSource(
                        uuid, source.Id)
                else:
                    #To support old instances that don't have Uuid attribute
                    uuid = str(uuid4().hex)
                    localPost = None

                if localPost == None:
                    if 'DeletedOn' in post: continue
                    localPost = Post()
                    localPost.Uuid = uuid
                    insert = True

                if 'DeletedOn' not in post:
                    #TODO: workaround, read again the Author because sometimes we get access denied
                    post['Author'] = self._readAuthor(post['Author']['href'])
                    post['Creator'] = self._readCreator(
                        post['Creator']['href'])

                    #if exists local, update it, otherwise continue the original insert
                    localPost.Type = post['Type']['Key']
                    localPost.Author, localPost.Creator, needUpdate, isAuthor = self._getCollaboratorForAuthor(
                        post['Author'], post['Creator'], source)
                    localPost.Feed = source.Id
                    localPost.Meta = post['Meta'] if 'Meta' in post else None
                    localPost.ContentPlain = post[
                        'ContentPlain'] if 'ContentPlain' in post else None
                    localPost.Content = post[
                        'Content'] if 'Content' in post else None
                    localPost.Order = post['Order'] if 'Order' in post else None
                    localPost.CreatedOn = current_timestamp()
                    if blogSync.Auto:
                        localPost.PublishedOn = current_timestamp()
                        localPost.WasPublished = True

                    log.info("received post: %s", str(localPost))

                    if localPost.Creator and (
                            localPost.Creator
                            not in usersForIcons) and needUpdate:
                        try:
                            if isAuthor:
                                usersForIcons[
                                    localPost.Creator] = post['Author']['User']
                            else:
                                usersForIcons[
                                    localPost.Creator] = post['Creator']
                        except KeyError:
                            pass

                else:
                    localPost.DeletedOn = datetime.strptime(
                        post['DeletedOn'], '%m/%d/%y %I:%M %p')

                # prepare the blog sync model to update the change identifier
                blogSync.CId = int(post['CId']) if blogSync.CId is None or int(
                    post['CId']) > blogSync.CId else blogSync.CId

                if insert:
                    self.blogPostService.insert(blogSync.Blog, localPost)
                else:
                    self.blogPostService.update(blogSync.Blog, localPost)

                # update blog sync entry
                blogSync.LastActivity = datetime.now().replace(microsecond=0)
                self.blogSyncService.update(blogSync)

            except KeyError as e:
                log.error('Post from source %s is missing attribute %s' %
                          (source.URI, e))
            except Exception as e:
                log.error('Error in source %s post: %s' % (source.URI, e))

        self._updateIcons(usersForIcons)

        blogSync.LastActivity = None
        self.blogSyncService.update(blogSync)
Exemplo n.º 7
0
    def addComment(self, blogId, comment):
        '''
        @see: IBlogCommentService.addComment
        '''
        # checking if the blog exists
        # checking whether comments are allowed shall be done in gateway
        if not self.session().query(exists().where(BlogMapped.Id == blogId)).scalar():
            raise InputError(Ref(_('Specified blog does not exist'),))

        userName = comment.UserName
        commentText = comment.CommentText
        commentSource = comment.CommentSource if comment.CommentSource else self.source_name_default

        # checking the necessary info: user name and comment text
        if not userName:
            raise InputError(Ref(_('No value for the mandatory UserName'),))
        if not commentText:
            raise InputError(Ref(_('No value for the mandatory CommentText'),))

        # take (or make) the user (for user name) part of creator and collaborator
        userTypeId, = self.session().query(UserTypeMapped.id).filter(UserTypeMapped.Key == self.user_type_key).one()
        try:
            sql = self.session().query(UserMapped.userId, UserMapped.Active)
            sql = sql.filter(UserMapped.typeId == userTypeId)
            sql = sql.filter(UserMapped.FirstName == userName)
            userId, isActive = sql.one()
            if not isActive:
                raise InputError(Ref(_('The commentator user was inactivated'),))
        except:
            user = User()
            user.FirstName = userName
            user.LastName = self.user_last_name
            user.Name = self._freeCommentUserName()
            user.Password = binascii.b2a_hex(os.urandom(32)).decode()
            user.Type = self.user_type_key
            userId = self.userService.insert(user)

        # make the source (for inlet type) part of collaborator
        try:
            sql = self.session().query(SourceMapped.Id).join(SourceTypeMapped)
            sql = sql.filter(SourceTypeMapped.Key == self.source_type_key).filter(SourceMapped.Name == commentSource)
            sourceId, = sql.one()
        except NoResultFound:
            source = Source()
            source.Type = self.source_type_key
            source.Name = commentSource
            source.URI = ''
            source.IsModifiable = True
            sourceId = self.sourceService.insert(source)

        # make the collaborator
        sql = self.session().query(CollaboratorMapped.Id)
        sql = sql.filter(CollaboratorMapped.Source == sourceId)
        sql = sql.filter(CollaboratorMapped.User == userId)
        try:
            collabId, = sql.one()
        except NoResultFound:
            collab = Collaborator()
            collab.Source = sourceId
            collab.User = userId
            collabId = self.collaboratorService.insert(collab)

        # create post request
        post = Post()
        post.Type = self.post_type_key
        post.Creator = userId
        post.Author = collabId
        post.Content = commentText
        post.CreatedOn = datetime.now()

        # insert the blog post
        postId = self.blogPostService.insert(blogId, post)

        return postId
Exemplo n.º 8
0
    def _syncChain(self, blogSync):
        '''
        Synchronize the blog for the given sync entry.

        @param blogSync: BlogSync
            The blog sync entry declaring the blog and source from which the blog
            has to be updated.
        '''
        assert isinstance(blogSync, BlogSync), 'Invalid blog sync %s' % blogSync
        source = self.sourceService.getById(blogSync.Source)
        
        log.info('_syncChain blogId=%d, sourceId=%d', blogSync.Blog, blogSync.Source)
        
        assert isinstance(source, Source)
        (scheme, netloc, path, params, query, fragment) = urlparse(source.URI)

        q = parse_qsl(query, keep_blank_values=True)
        q.append(('asc', 'cId'))
        q.append(('cId.since', blogSync.CId if blogSync.CId is not None else 0))

        url = urlunparse((scheme, netloc, path + '/' + self.published_posts_path, params, urlencode(q), fragment))
        req = Request(url, headers={'Accept' : self.acceptType, 'Accept-Charset' : self.encodingType,
                                    'X-Filter' : '*,Creator.*,Author.User.*,Author.Source.*', 'User-Agent' : 'Magic Browser'})
        
        try: resp = urlopen(req)
        except (HTTPError, socket.error) as e:
            log.error('Read error on %s: %s' % (source.URI, e))
            return
        if str(resp.status) != '200':
            log.error('Read problem on %s, status: %s' % (source.URI, resp.status))
            return

        try: msg = json.load(codecs.getreader(self.encodingType)(resp))
        except ValueError as e:
            log.error('Invalid JSON data %s' % e)
            return

        usersForIcons = {}
        for post in msg['PostList']:
            try:
                if post['IsPublished'] != 'True': continue
                
                insert = False 
                if 'Uuid' in post: 
                    uuid = post['Uuid']
                    localPost = self.postService.getByUuidAndSource(uuid, source.Id) 
                else: 
                    #To support old instances that don't have Uuid attribute
                    uuid = str(uuid4().hex)
                    localPost = None 
                    
                if localPost == None:  
                    if 'DeletedOn' in post: continue    
                    localPost = Post()
                    localPost.Uuid = uuid
                    insert = True
                
                if 'DeletedOn' not in post:       
                    #TODO: workaround, read again the Author because sometimes we get access denied
                    post['Author'] = self._readAuthor(post['Author']['href'])   
                    post['Creator'] = self._readCreator(post['Creator']['href'])
                    
                    #if exists local, update it, otherwise continue the original insert
                    localPost.Type = post['Type']['Key']
                    localPost.Author, localPost.Creator, needUpdate, isAuthor = self._getCollaboratorForAuthor(post['Author'], post['Creator'], source)
                    localPost.Feed = source.Id
                    localPost.Meta = post['Meta'] if 'Meta' in post else None
                    localPost.ContentPlain = post['ContentPlain'] if 'ContentPlain' in post else None
                    localPost.Content = post['Content'] if 'Content' in post else None
                    localPost.Order = post['Order'] if 'Order' in post else None
                    localPost.CreatedOn = current_timestamp()              
                    if blogSync.Auto: 
                        localPost.PublishedOn = current_timestamp()
                        localPost.WasPublished = True
                    
                    log.info("received post: %s", str(localPost))
      
                    if localPost.Creator and (localPost.Creator not in usersForIcons) and needUpdate:
                        try:
                            if isAuthor: usersForIcons[localPost.Creator] = post['Author']['User']
                            else: usersForIcons[localPost.Creator] = post['Creator']
                        except KeyError:
                            pass
                    
                else:
                    localPost.DeletedOn = datetime.strptime(post['DeletedOn'], '%m/%d/%y %I:%M %p')
                            
                # prepare the blog sync model to update the change identifier
                blogSync.CId = int(post['CId']) if blogSync.CId is None or int(post['CId']) > blogSync.CId else blogSync.CId

                if insert: self.blogPostService.insert(blogSync.Blog, localPost)
                else: self.blogPostService.update(blogSync.Blog, localPost)
                
                # update blog sync entry
                blogSync.LastActivity = datetime.now().replace(microsecond=0)
                self.blogSyncService.update(blogSync)
                
            except KeyError as e:
                log.error('Post from source %s is missing attribute %s' % (source.URI, e))
            except Exception as e:
                log.error('Error in source %s post: %s' % (source.URI, e))

        self._updateIcons(usersForIcons)
        
        blogSync.LastActivity = None 
        self.blogSyncService.update(blogSync)
Exemplo n.º 9
0
    def pushMessage(self, typeKey, phoneNumber=None, messageText=None, timeStamp=None):
        '''
        @see: IInletService.pushMessage
        '''
        # checking the necessary info: phone number and message text
        if (phoneNumber is None) or (phoneNumber == ''):
            raise InputError(Ref(_('No value for the mandatory phoneNumber parameter'),))
        if (messageText is None) or (messageText == ''):
            raise InputError(Ref(_('No value for the mandatory messageText parameter'),))

        # take (or make) the user (for phone number) part of creator and collaborator
        try:
            userId, = self.session().query(PersonMapped.Id).filter(PersonMapped.PhoneNumber == phoneNumber).one()
        except:
            user = User()
            user.PhoneNumber = phoneNumber
            user.Name = self._freeSMSUserName()
            user.Password = binascii.b2a_hex(os.urandom(32)).decode()
            user.Type = self.user_type_key
            userId = self.userService.insert(user)

        # make the source (for inlet type) part of collaborator
        try:
            sql = self.session().query(SourceMapped.Id).join(SourceTypeMapped)
            sql = sql.filter(SourceTypeMapped.Key == self.sms_source_type_key).filter(SourceMapped.Name == typeKey)
            sourceId, = sql.one()
        except NoResultFound:
            source = Source()
            source.Type = self.sms_source_type_key
            source.Name = typeKey
            source.URI = ''
            source.IsModifiable = True
            sourceId = self.sourceService.insert(source)

        # make the collaborator
        sql = self.session().query(CollaboratorMapped.Id)
        sql = sql.filter(CollaboratorMapped.Source == sourceId)
        sql = sql.filter(CollaboratorMapped.User == userId)
        try:
            collabId, = sql.one()
        except NoResultFound:
            collab = Collaborator()
            collab.Source = sourceId
            collab.User = userId
            collabId = self.collaboratorService.insert(collab)

        # take / make time stamp
        if timeStamp:
            try:
                timeStamp = datetime.strptime(timeStamp, '%Y-%m-%d %H:%M:%S.%f')
            except:
                timeStamp = None

        if not timeStamp:
            timeStamp = datetime.now()

        # create post request
        post = Post()
        post.Type = self.sms_post_type_key
        post.Creator = userId
        post.Author = collabId
        post.Content = messageText
        post.CreatedOn = timeStamp

        # insert the post
        postId = self.postService.insert(post)

        return (self.postService.getById(postId),)
Exemplo n.º 10
0
    def pushMessage(self,
                    typeKey,
                    phoneNumber=None,
                    messageText=None,
                    timeStamp=None):
        '''
        @see: IInletService.pushMessage
        '''
        # checking the necessary info: phone number and message text
        if (phoneNumber is None) or (phoneNumber == ''):
            raise InputError(
                Ref(_('No value for the mandatory phoneNumber parameter'), ))
        if (messageText is None) or (messageText == ''):
            raise InputError(
                Ref(_('No value for the mandatory messageText parameter'), ))

        # take (or make) the user (for phone number) part of creator and collaborator
        try:
            userId, = self.session().query(PersonMapped.Id).filter(
                PersonMapped.PhoneNumber == phoneNumber).one()
        except:
            user = User()
            user.PhoneNumber = phoneNumber
            user.Name = self._freeSMSUserName()
            user.Password = binascii.b2a_hex(os.urandom(32)).decode()
            user.Type = self.user_type_key
            userId = self.userService.insert(user)

        # make the source (for inlet type) part of collaborator
        try:
            sql = self.session().query(SourceMapped.Id).join(SourceTypeMapped)
            sql = sql.filter(
                SourceTypeMapped.Key == self.sms_source_type_key).filter(
                    SourceMapped.Name == typeKey)
            sourceId, = sql.one()
        except NoResultFound:
            source = Source()
            source.Type = self.sms_source_type_key
            source.Name = typeKey
            source.URI = ''
            source.IsModifiable = True
            sourceId = self.sourceService.insert(source)

        # make the collaborator
        sql = self.session().query(CollaboratorMapped.Id)
        sql = sql.filter(CollaboratorMapped.Source == sourceId)
        sql = sql.filter(CollaboratorMapped.User == userId)
        try:
            collabId, = sql.one()
        except NoResultFound:
            collab = Collaborator()
            collab.Source = sourceId
            collab.User = userId
            collabId = self.collaboratorService.insert(collab)

        # take / make time stamp
        if timeStamp:
            try:
                timeStamp = datetime.strptime(timeStamp,
                                              '%Y-%m-%d %H:%M:%S.%f')
            except:
                timeStamp = None

        if not timeStamp:
            timeStamp = datetime.now()

        # create post request
        post = Post()
        post.Type = self.sms_post_type_key
        post.Creator = userId
        post.Author = collabId
        post.Content = messageText
        post.CreatedOn = timeStamp

        # insert the post
        postId = self.postService.insert(post)

        return (self.postService.getById(postId), )
Exemplo n.º 11
0
    def addComment(self, blogId, comment):
        '''
        @see: IBlogCommentService.addComment
        '''
        # checking if the blog exists
        # checking whether comments are allowed shall be done in gateway
        if not self.session().query(
                exists().where(BlogMapped.Id == blogId)).scalar():
            raise InputError(Ref(_('Specified blog does not exist'), ))

        userName = comment.UserName
        commentText = comment.CommentText
        commentSource = comment.CommentSource if comment.CommentSource else self.source_name_default

        # checking the necessary info: user name and comment text
        if not userName:
            raise InputError(Ref(_('No value for the mandatory UserName'), ))
        if not commentText:
            raise InputError(Ref(
                _('No value for the mandatory CommentText'), ))

        # take (or make) the user (for user name) part of creator and collaborator
        userTypeId, = self.session().query(UserTypeMapped.id).filter(
            UserTypeMapped.Key == self.user_type_key).one()
        try:
            sql = self.session().query(UserMapped.userId, UserMapped.Active)
            sql = sql.filter(UserMapped.typeId == userTypeId)
            sql = sql.filter(UserMapped.FirstName == userName)
            userId, isActive = sql.one()
            if not isActive:
                raise InputError(
                    Ref(_('The commentator user was inactivated'), ))
        except:
            user = User()
            user.FirstName = userName
            user.LastName = self.user_last_name
            user.Name = self._freeCommentUserName()
            user.Password = binascii.b2a_hex(os.urandom(32)).decode()
            user.Type = self.user_type_key
            userId = self.userService.insert(user)

        # make the source (for inlet type) part of collaborator
        try:
            sql = self.session().query(SourceMapped.Id).join(SourceTypeMapped)
            sql = sql.filter(
                SourceTypeMapped.Key == self.source_type_key).filter(
                    SourceMapped.Name == commentSource)
            sourceId, = sql.one()
        except NoResultFound:
            source = Source()
            source.Type = self.source_type_key
            source.Name = commentSource
            source.URI = ''
            source.IsModifiable = True
            sourceId = self.sourceService.insert(source)

        # make the collaborator
        sql = self.session().query(CollaboratorMapped.Id)
        sql = sql.filter(CollaboratorMapped.Source == sourceId)
        sql = sql.filter(CollaboratorMapped.User == userId)
        try:
            collabId, = sql.one()
        except NoResultFound:
            collab = Collaborator()
            collab.Source = sourceId
            collab.User = userId
            collabId = self.collaboratorService.insert(collab)

        # create post request
        post = Post()
        post.Type = self.post_type_key
        post.Creator = userId
        post.Author = collabId
        post.Content = commentText
        post.CreatedOn = datetime.now()

        # insert the blog post
        postId = self.blogPostService.insert(blogId, post)

        return postId
Exemplo n.º 12
0
    def _syncSms(self, blogSync):
        """
        Synchronize the sms for the given sync entry.

        @param smsSync: SmsSync
            The sms sync entry declaring the blog and source from which the blog
            has to be updated.
        """
        assert isinstance(blogSync, BlogSync), "Invalid blog sync %s" % blogSync
        source = self.sourceService.getById(blogSync.Source)
        assert isinstance(source, Source)

        providerId = self.sourceService.getOriginalSource(source.Id)

        log.info(
            "sync sms for sourceId=%i, providerId=%i, blogId=%i, lastId=%i"
            % (blogSync.Source, providerId, blogSync.Blog, blogSync.CId)
        )

        q = QPost()
        q.cId.since = str(blogSync.CId)

        posts = self.postService.getAllBySource(providerId, q=q)

        for post in posts:
            try:

                log.info("post: Id=%i, content=%s, sourceId=%i" % (post.Id, post.Content, blogSync.Source))

                smsPost = Post()
                smsPost.Type = post.Type
                smsPost.Uuid = post.Uuid
                smsPost.Creator = post.Creator
                smsPost.Feed = source.Id
                smsPost.Meta = post.Meta
                smsPost.ContentPlain = post.ContentPlain
                smsPost.Content = post.Content
                smsPost.CreatedOn = current_timestamp()

                # make the collaborator
                sql = self.collaboratorService.session().query(CollaboratorMapped.Id)
                sql = sql.filter(CollaboratorMapped.Source == blogSync.Source)
                sql = sql.filter(CollaboratorMapped.User == post.Creator)
                try:
                    collaboratorId, = sql.one()
                except NoResultFound:
                    collaborator = Collaborator()
                    collaborator.Source = blogSync.Source
                    collaborator.User = post.Creator
                    collaboratorId = self.collaboratorService.insert(collaborator)

                smsPost.Author = collaboratorId

                # prepare the sms sync model to update the change identifier
                blogSync.CId = post.Id if post.Id > blogSync.CId else blogSync.CId

                # insert post from remote source
                self.blogPostService.insert(blogSync.Blog, smsPost)

                # update blog sync entry
                blogSync.LastActivity = datetime.datetime.now().replace(microsecond=0)
                self.blogSyncService.update(blogSync)

            except Exception as e:
                log.error("Error in source %s post: %s" % (source.URI, e))

        blogSync.LastActivity = None
        self.blogSyncService.update(blogSync)