def getMsgsForChild(cname): '''Find all new messages for a single child''' dtype = surllib.getBrowser().getState('dialogue') if dtype == 'conversations': # New more "gmail" like message view url = schildren.getChildURL(cname, '/messages/conversations') config.clog(cname, u'Kigger efter nye beskeder på %s' % url) bs = surllib.skoleGetURL(url, asSoup=True, noCache=True) return parseMessages(cname, bs) elif dtype == 'inbox': # Old message view msgs = [] for tray in ['inbox', 'outbox']: url = schildren.getChildURL(cname, '/messages/' + tray) config.clog(cname, u'Kigger efter nye beskeder på %s' % url) bs = surllib.skoleGetURL(url, asSoup=True, noCache=True) msgs += parseTrayMessages(cname, bs) return msgs else: config.clog(cname, u'Beskede-indbakke-type %r ikke understøttet' % dtype, 0) return []
def getMsgsForChild(cname): '''Find all new messages for a single child''' dtype = surllib.getBrowser().getState('dialogue') if dtype == 'conversations': # New more "gmail" like message view url = schildren.getChildURL(cname, '/messages/conversations') config.clog(cname, u'Kigger efter nye beskeder på %s' % url) bs = surllib.skoleGetURL(url, asSoup=True, noCache=True) return parseMessages(cname, bs) elif dtype == 'inbox': # Old message view msgs = [] for tray in ['inbox', 'outbox']: url = schildren.getChildURL(cname, '/messages/'+tray) config.clog(cname, u'Kigger efter nye beskeder på %s' % url) bs = surllib.skoleGetURL(url, asSoup=True, noCache=True) msgs += parseTrayMessages(cname, bs) return msgs else: config.clog(cname, u'Beskede-indbakke-type %r ikke understøttet' % dtype, 0) return []
def markMessageAsRead(cname, mid, isRead=True): assert (type(mid) in [str, unicode]) isRead = 'true' if isRead else 'false' url = schildren.getChildURL(cname, '/messages/UpdateMessagesReadState') data = {'selectionState[MessageIds][]': mid, 'isRead': isRead} config.clog(cname, u'Markerer besked #%s som læst' % mid, 3) surllib.skoleGetURL(url, noCache=True, postData=data)
def getMsgsForChild(cname): '''Look for new frontpage news''' url = schildren.getChildURL(cname, '/Index') config.clog(cname, u'Behandler forsiden %s' % url) bs = surllib.skoleGetURL(url, asSoup=True, noCache=True) return parseFrontpage(cname, bs)
def markMessageAsRead(cname, mid, isRead=True): assert(type(mid) in [str, unicode]) isRead = 'true' if isRead else 'false' url = schildren.getChildURL(cname, '/messages/UpdateMessagesReadState') data = {'selectionState[MessageIds][]': mid, 'isRead': isRead} config.clog(cname, u'Markerer besked #%s som læst' % mid, 3) surllib.skoleGetURL(url, noCache=True, postData=data)
def skoleSignup(cname): 'Tilmelding til samtaler/arrangementer' config.clog(cname, u'Kigger efter nye samtaler/arrangementer') for suffix in ('conversation', 'event'): url = schildren.getChildURL(cname, '/signup/' + suffix) bs = surllib.skoleGetURL(url, True, MAX_CACHE_AGE) findEvents(cname, bs)
def skolePhotos(cname): 'Billeder' url = schildren.getChildURL(cname, '/photos/archives') bs = surllib.skoleGetURL(url, True, MAX_CACHE_AGE) config.clog(cname, u'Kigger efter billeder') findPhotos(cname, bs)
def skoleContacts(cname): 'Kontaktinformation' config.clog(cname, u'Kigger efter ny kontaktinformation') url = schildren.getChildURL(cname, '/contacts/students/cards') bs = surllib.skoleGetURL(url, True, MAX_CACHE_AGE) opts = bs.select('#sk-toolbar-contact-dropdown option') if not opts: config.clog(cname, u'Kan ikke finde nogen elever?') return for opt in opts: url = opt['value'] bs2 = surllib.skoleGetURL(url, True, bs.cacheage + .01) contactCard(cname, bs2)
def skoleWeekplans(cname): 'Ugeplaner' config.clog(cname, u'Kigger efter nye ugeplaner') url = schildren.getChildURL(cname, 'item/weeklyplansandhomework/list/') bs = surllib.skoleGetURL(url, True, noCache=True) ul = bs.find('ul', 'sk-weekly-plans-list-container') if ul: for a in ul.find_all('a', href=True): url = a['href'] plan = getWeekplan(cname, url) wid = url.split('/')[-1] # e.g. 35-2018 title = plan.find('h3').text.strip() msg = semail.Message(cname, SECTION, unicode(plan)) msg.setTitle(title) msg.setMessageID(wid) msg.maybeSend() else: if u'ikke autoriseret' in bs.text: config.clog(cname, u'Din skole bruger ikke ugeplaner. ' u"Du bør bruge '--section ,-%s'" % SECTION)
def skoleDocuments(cname): 'Dokumenter' for rootTitle, folder in [('Klassens dokumenter', 'class')]: config.clog(cname, u'%s: Kigger efter dokumenter' % rootTitle) url = schildren.getChildURL(cname, '/documents/' + folder) bs = surllib.skoleGetURL(url, True, MAX_CACHE_AGE) docFindDocuments(cname, rootTitle, bs, '') # look for sub folders js = bs.find(id='FoldersJson') if js and js.has_attr('value'): sfs = json.loads(js['value']) for sf in sfs: if sf[u'Name'].startswith('$'): continue title = sf[u'Title'] url = sf[u'Url'] bs = surllib.skoleGetURL(url, True, MAX_CACHE_AGE, None, True) docFindDocuments(cname, rootTitle, bs, title)
def skoleWeekplans(cname): 'Ugeplaner' config.clog(cname, u'Kigger efter nye ugeplaner') url = schildren.getChildURL(cname, 'item/weeklyplansandhomework/list/') bs = surllib.skoleGetURL(url, True, noCache=True) ul = bs.find('ul', 'sk-weekly-plans-list-container') if ul: for a in ul.find_all('a', href=True): url = a['href'] plan = getWeekplan(cname, url) wid = url.split('/')[-1] # e.g. 35-2018 title = plan.find('h3').text.strip() msg = semail.Message(cname, SECTION, unicode(plan)) msg.setTitle(title) msg.setMessageID(wid) msg.maybeSend() else: if u'ikke autoriseret' in bs.text: config.clog( cname, u'Din skole bruger ikke ugeplaner. ' u"Du bør bruge '--section ,-%s'" % SECTION)
def parseMessages(cname, bs): '''Look for new messages in each conversation''' # Look for a div with a very long attribute with json main = bs.find('div', 'sk-l-content-wrapper') conversations = None for d in main.findAll('div'): for a in d.attrs: if 'message' not in a.lower() or len(d[a]) < 100: continue try: jsn = json.loads(d[a]) if type(jsn) == dict: conversations = jsn.get('Conversations') break except ValueError: continue if not conversations: config.clog(cname, 'Ingen beskeder fundet?!?', -1) return [] emsgs = [] for i, c in enumerate(conversations[::1]): tid = c.get('ThreadId') lmid = unicode(c.get('LatestMessageId')) if not tid: # ThreadId can be empty if this is a msg to all students tid = '' if not lmid: config.clog(cname, u'Noget galt i tråd #%d %r %r' % (i, tid, lmid), -1) continue if semail.hasSentMessage(tp=SECTION, mid=(tid, lmid)): continue # This last messages has not been seen - load the entire conversation if tid: suffix = ( '/messages/conversations/loadmessagesforselectedconversation' + '?threadId=' + tid + '&takeFromRootMessageId=' + lmid + '&takeToMessageId=0' + '&searchRequest=') else: suffix = ( '/messages/conversations/getmessageforthreadlessconversation' + '?messageId=' + lmid) curl = schildren.getChildURL(cname, suffix) data = surllib.skoleGetURL(curl, asSoup=False, noCache=True, addTimeSuffix=True) try: jsn = json.loads(data) except ValueError: config.clog(cname, 'Kan ikke indlæse besked-listen i tråd %d %r %r' % (i, tid, lmid), -1) continue msgs = jsn if tid else [jsn] assert(type(msgs) == list) for jsn in msgs[::-1]: mid = unicode(jsn.get('Id')) if semail.hasSentMessage(tp=SECTION, mid=(tid, mid)): continue # Generate new messages with this content emsgs.append(msgFromJson(cname, jsn, tid)) return emsgs
def parseFrontpageItem(cname, div): '''Parse a single frontpage news item''' # Do we have any comments? comments = div.find('div', 'sk-news-item-comments') cdiv = u'' if comments: global c # Comments are enabled txt = comments.text.strip() if u'tilføj' not in txt.lower(): m = re.match(ur'.*vis (\d+) kommentar.*', txt.lower()) assert(m) nc = int(m.group(1)) if nc > 0: suff = '/news/pins/%s/comments' % div['data-feed-item-id'] url = schildren.getChildURL(cname, suff) bs = surllib.skoleGetURL(url, asSoup=True, postData={'_': str(nc)}) cdiv = unicode(bs.find('div', 'sk-comments-container')) cdiv = u'<br>' + cdiv author = div.find('div', 'sk-news-item-author') body = div.find('div', 'sk-news-item-content') # trim the body a bit body = sbs4.copy(body) # make a copy as we look for attachments later for e in body.select('.sk-attachments-list, .sk-news-item-comments'): e.extract() for e in body.select('.h-fnt-bd'): e['style'] = 'font-weight: bold' for e in body.select('div'): # remove empty divs contents = u''.join(map(unicode, e.children)).strip() if not contents: e.extract() # Trim extra white space - sometimes unecessary linebreaks are introduced sbs4.trimSoup(body) msg = semail.Message(cname, SECTION, unicode(body)+cdiv) for e in body.select('span, strong, b, i'): e.unwrap() sbs4.condenseSoup(body) title = body.get_text(u'\n', strip=True).strip().split(u'\n')[0] title = title.replace(u'\xa0', u' ').strip() title = u' '.join(title.rstrip(u' .').split()) msg.setTitle(title, True) msg.setMessageID(div['data-feed-item-id']) msg.setSender(author.span.text) # Find list of recipients author.span.extract() # Remove author for tag in [ author.span, # Remove author author.find('span', 'sk-news-item-for'), # Remove 'til' author.find('span', 'sk-news-item-and'), # Remove ' og ' author.find('a', 'sk-news-show-more-link')]: if tag: tag.extract() recp = re.sub(ur'\s*(,| og )\s*', ',', author.text.strip()) recp = recp.split(u',') msg.setRecipient(recp) msg.setDateTime(div.find('div', 'sk-news-item-timestamp').text) # Do we have any attachments? divA = div.find('div', 'sk-attachments-list') if divA: for att in (divA.findAll('a') or []): url = att['href'] text = att.text.strip() msg.addAttachment(url, text) return msg
def parseFrontpageItem(cname, div): '''Parse a single frontpage news item''' # Do we have any comments? comments = div.find('div', 'sk-news-item-comments') cdiv = u'' if comments: global c # Comments are enabled txt = comments.text.strip() if u'tilføj' not in txt.lower(): m = re.match(ur'.*vis (\d+) kommentar.*', txt.lower()) assert (m) nc = int(m.group(1)) if nc > 0: suff = '/news/pins/%s/comments' % div['data-feed-item-id'] url = schildren.getChildURL(cname, suff) bs = surllib.skoleGetURL(url, asSoup=True, postData={'_': str(nc)}) cdiv = unicode(bs.find('div', 'sk-comments-container')) cdiv = u'<br>' + cdiv author = div.find('div', 'sk-news-item-author') body = div.find('div', 'sk-news-item-content') # trim the body a bit body = sbs4.copy(body) # make a copy as we look for attachments later for e in body.select('.sk-news-item-footer, .sk-news-item-comments'): e.extract() for e in body.select('.h-fnt-bd'): e['style'] = 'font-weight: bold' for e in body.select('div'): # remove empty divs contents = u''.join(map(unicode, e.children)).strip() if not contents: e.extract() # Trim extra white space - sometimes unecessary linebreaks are introduced sbs4.trimSoup(body) msg = semail.Message(cname, SECTION, unicode(body) + cdiv) for e in body.select('span, strong, b, i'): e.unwrap() sbs4.condenseSoup(body) title = body.get_text(u'\n', strip=True).strip().split(u'\n')[0] title = title.replace(u'\xa0', u' ').strip() title = u' '.join(title.rstrip(u' .').split()) msg.setTitle(title, True) msg.setMessageID(div['data-feed-item-id']) msg.setSender(author.span.text) # Find list of recipients author.span.extract() # Remove author for tag in [ author.span, # Remove author author.find('span', 'sk-news-item-for'), # Remove 'til' author.find('span', 'sk-news-item-and'), # Remove ' og ' author.find('a', 'sk-news-show-more-link') ]: if tag: tag.extract() recp = re.sub(ur'\s*(,| og )\s*', ',', author.text.strip()) recp = recp.split(u',') msg.setRecipient(recp) msg.setDateTime(div.find('div', 'sk-news-item-timestamp').text) # Do we have any attachments? divA = div.find('div', 'sk-attachments-list') if divA: for att in (divA.findAll('a') or []): url = att['href'] text = att.text.strip() msg.addAttachment(url, text) return msg
def parseMessages(cname, bs): '''Look for new messages in each conversation''' # Look for a div with a very long attribute with json main = bs.find('div', 'sk-l-content-wrapper') conversations = None for d in main.findAll('div'): for a in d.attrs: if 'message' not in a.lower() or len(d[a]) < 100: continue try: jsn = json.loads(d[a]) if type(jsn) == dict: conversations = jsn.get('Conversations') break except ValueError: continue if not conversations: config.clog(cname, 'Ingen beskeder fundet?!?', -1) return [] emsgs = [] for i, c in enumerate(conversations[::1]): tid = c.get('ThreadId') lmid = unicode(c.get('LatestMessageId')) if not tid: # ThreadId can be empty if this is a msg to all students tid = '' if not lmid: config.clog(cname, u'Noget galt i tråd #%d %r %r' % (i, tid, lmid), -1) continue if semail.hasSentMessage(tp=SECTION, mid=(tid, lmid)): continue # This last messages has not been seen - load the entire conversation if tid: suffix = ( '/messages/conversations/loadmessagesforselectedconversation' + '?threadId=' + tid + '&takeFromRootMessageId=' + lmid + '&takeToMessageId=0' + '&searchRequest=') else: suffix = ( '/messages/conversations/getmessageforthreadlessconversation' + '?messageId=' + lmid) curl = schildren.getChildURL(cname, suffix) data = surllib.skoleGetURL(curl, asSoup=False, noCache=True, addTimeSuffix=True) try: jsn = json.loads(data) except ValueError: config.clog( cname, 'Kan ikke indlæse besked-listen i tråd %d %r %r' % (i, tid, lmid), -1) continue msgs = jsn if tid else [jsn] assert (type(msgs) == list) for jsn in msgs[::-1]: mid = unicode(jsn.get('Id')) if semail.hasSentMessage(tp=SECTION, mid=(tid, mid)): continue # Generate new messages with this content emsgs.append(msgFromJson(cname, jsn, tid)) return emsgs