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
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)
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)
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),)
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), )
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
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)