def parseTrayMessages(cname, bs): '''Look for new messages in a message tray (old message view)''' msgs = [] for div in bs.select('.sk-message-list-item'): url = div.find('a')['href'] mid = re.findall('(?<=/message/)[0-9]+', url) assert(len(mid) == 1 and mid[0]) mid = mid[0] sender = div.find('li', 'sk-message-senderrecipient-name').text.strip() m = re.match(r'^([^(]*) \(.*\)$', sender) if m: sender = m.group(1) # We could also get the title title = div.find('div', 'sk-message-title').text.strip() if semail.hasSentMessage(tp=SECTION, mid=mid): continue config.clog(cname, u'Henter ny besked: %s - %s' % (sender, title), 2) bs = surllib.skoleGetURL(url, True) msg = parseTrayMessage(cname, bs, mid, sender) msgs.append(msg) return msgs
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 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 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 parseTrayMessages(cname, bs): '''Look for new messages in a message tray (old message view)''' msgs = [] for div in bs.select('.sk-message-list-item'): url = div.find('a')['href'] mid = re.findall('(?<=/message/)[0-9]+', url) assert (len(mid) == 1 and mid[0]) mid = mid[0] sender = div.find('li', 'sk-message-senderrecipient-name').text.strip() m = re.match(r'^([^(]*) \(.*\)$', sender) if m: sender = m.group(1) # We could also get the title title = div.find('div', 'sk-message-title').text.strip() if semail.hasSentMessage(tp=SECTION, mid=mid): continue config.clog(cname, u'Henter ny besked: %s - %s' % (sender, title), 2) bs = surllib.skoleGetURL(url, True) msg = parseTrayMessage(cname, bs, mid, sender) msgs.append(msg) return msgs
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 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 parseFrontpage(cname, bs): '''Look for new frontpage news items''' msgs = [] # Find potential interesting events today in the sidebar ul = bs.find('ul', 'sk-reminders-container') if ul: for li in ul.findAll('li', recursive=False): for c in li.contents: uc = unicode(c).strip().lower() if not uc: continue if u'har fødselsdag' in uc: today = unicode(time.strftime(u'%d. %b. %Y')) c.append(u" \U0001F1E9\U0001F1F0") # Unicode DK Flag sbs4.appendTodayComment(c) msg = semail.Message(cname, SECTION, unicode(c)) msg.setTitle(c.text.strip()) msg.setDateTime(today) msgs.append(msg) elif u'der er aktiviteter i dag' in uc: continue # ignore else: config.clog(cname, u'Hopper mini-besked %r over' % c.text.strip(), 2) # Find interesting main front page items fps = bs.findAll('div', 'sk-news-item') assert(len(fps) > 0) # 1+ msgs on the frontpage or something is wrong for div in fps[::-1]: msg = parseFrontpageItem(cname, div) msgs.append(msg) return msgs
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 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 docFindDocuments(cname, rootTitle, bs, title): '''Search a folder for new documents''' folder = rootTitle if title: folder += u' / ' + title.replace(u'>', u'/') docs = bs.findAll('div', 'sk-document') config.clog(cname, u'%s: %d dokumenter fundet ' % (folder, len(docs))) for doc in docs: docTitle = doc.find('span', 'sk-documents-document-title').text.strip() docDate = doc.find('div', 'sk-documents-date-column').text.strip() a = doc.find('a') url = a and a['href'] or '' if '.' in docTitle: sfn = docTitle.rsplit(u'.', 1)[0] else: sfn = docTitle if docTitle and docDate and url: # Create HTML snippet html = u"<p>Nyt dokument: <span></span> / <b></b></p>\n" html += u"<!-- Sidst opdateret: %s -->" % docDate h = sbs4.beautify(html) h.span.string = folder h.b.string = docTitle msg = semail.Message(cname, SECTION, unicode(h)) msg.setTitle(sfn) msg.setDateTime(docDate) msg.addAttachment(url, docTitle) msg.setMessageID(url.split('/')[-1]) msg.maybeSend()
def findPhotos(cname, bs): prefix = schildren.getChildURLPrefix(cname) for opt in bs.select('#sk-photos-toolbar-filter option'): if not opt.has_attr('value'): continue url = surllib.absurl(opt['value']) folder = opt.text.strip() if not url.startswith(prefix): config.clog(cname, u'Billeder: %s: ukendt URL %r' % (folder, opt['value'])) continue bs2 = surllib.skoleGetURL(url, True, MAX_CACHE_AGE) findPhotosInFolder(cname, url, bs2)
def findPhotos(cname, bs): prefix = schildren.getChildURLPrefix(cname) for opt in bs.select('#sk-photos-toolbar-filter option'): if not opt.has_attr('value'): continue url = surllib.absurl(opt['value']) folder = opt.text.strip() if not url.startswith(prefix): config.clog( cname, u'Billeder: %s: ukendt URL %r' % (folder, opt['value'])) continue bs2 = surllib.skoleGetURL(url, True, MAX_CACHE_AGE) findPhotosInFolder(cname, url, bs2)
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 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 skoleFrontpage(cnames): 'Forside inkl. opslagstavle' msgs = collections.OrderedDict() for cname in cnames: for msg in getMsgsForChild(cname): if msg.hasBeenSent(): continue config.clog(cname, u'Ny besked fundet: %s' % msg.mp['title'], 2) mid = msg.getLongMessageID() if mid in msgs: msgs[mid].addChild(cname) else: msgs[mid] = msg for mid, msg in msgs.items(): cname = ','.join(msg.mp['children']) config.clog(cname, u'Sender ny besked: %s' % msg.mp['title'], 2) msg.maybeSend()
def skoleFrontpage(cnames): 'Forside inkl. opslagstavle' msgs = collections.OrderedDict() for cname in cnames: for msg in getMsgsForChild(cname): if msg.hasBeenSent(): continue config.clog(cname, u'Ny besked fundet: %s' % msg.mp['title'], 2) mid = msg.getLongMessageID() if mid in msgs: msgs[mid].addChild(cname) else: msgs[mid] = msg for mid, msg in msgs.items(): cname = ','.join(msg.mp['children']) config.clog(cname, u'Sender ny besked: %s' % msg.mp['title'], 2) msg.maybeSend()
def findPhotosInFolder(cname, url, bs): '''Search a folder for new photos''' title = bs.h2.text.strip() mid = md5.md5(url.encode('utf-8')).hexdigest()[::2] photos = [] for img in bs.select('img'): if not img.has_attr('src'): continue url = surllib.absurl(img['src']) photos.append(url) ptext = u'%d billeder' % len(photos) if len(photos) != 1 else '1 billede' config.clog(cname, u'Billeder: %s: %s' % (title, ptext)) if not photos: return sendPhotos(cname, title, mid, photos)
def findPhotosInFolder(cname, url, bs): '''Search a folder for new photos''' title = bs.h2.text.strip() mid = md5.md5(url.encode('utf-8')).hexdigest()[::2] photos = [] for img in bs.select('img'): if not img.has_attr('src'): continue url = surllib.absurl(img['src']) photos.append(url) ptext = u'%d billeder' % len(photos) if len(photos) != 1 else '1 billede' config.clog(cname, u'Billeder: %s: %s' % (title, ptext)) if not photos: return sendPhotos(cname, title, mid, photos)
def skoleDialogue(cnames): 'Beskeder' msgs = collections.OrderedDict() for cname in cnames: for msg in getMsgsForChild(cname): if msg.hasBeenSent(): continue mid = msg.getLongMessageID() if mid in msgs: msgs[mid].addChild(cname) else: msgs[mid] = msg for mid, msg in msgs.items(): cname = ','.join(msg.mp['children']) config.clog(cname, u'Ny besked fundet: %s' % msg.mp['title']) msg.maybeSend() if msg.mp['data']['unread']: for cn in msg.getChildren(): smid = msg.getMessageID().split('--')[-1] markMessageAsRead(cn, smid)
def skoleDialogue(cnames): 'Beskeder' msgs = collections.OrderedDict() for cname in cnames: for msg in getMsgsForChild(cname): if msg.hasBeenSent(): continue mid = msg.getLongMessageID() if mid in msgs: msgs[mid].addChild(cname) else: msgs[mid] = msg for mid, msg in msgs.items(): cname = ','.join(msg.mp['children']) config.clog(cname, u'Ny besked fundet: %s' % msg.mp['title']) msg.maybeSend() if msg.mp['data']['unread']: for cn in msg.getChildren(): smid = msg.getMessageID().split('--')[-1] markMessageAsRead(cn, smid)
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 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 parseFrontpage(cname, bs): '''Look for new frontpage news items''' msgs = [] # Find potential interesting events today in the sidebar ul = bs.find('ul', 'sk-reminders-container') if ul: for li in ul.findAll('li', recursive=False): for c in li.contents: uc = unicode(c).strip().lower() if not uc: continue if u'har fødselsdag' in uc: today = unicode(time.strftime(u'%d. %b. %Y')) c.append(u" \U0001F1E9\U0001F1F0") # Unicode DK Flag sbs4.appendTodayComment(c) msg = semail.Message(cname, SECTION, unicode(c)) msg.setTitle(c.text.strip()) msg.setDateTime(today) msgs.append(msg) elif u'der er aktiviteter i dag' in uc: continue # ignore else: config.clog(cname, u'Hopper mini-besked %r over' % c.text.strip(), 2) # Find interesting main front page items fps = bs.findAll('div', 'sk-news-item') assert (len(fps) > 0) # 1+ msgs on the frontpage or something is wrong for div in fps[::-1]: msg = parseFrontpageItem(cname, div) msgs.append(msg) return msgs
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 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