Esempio n. 1
0
def dbopen(environ, db_basename):
	stderr = environ['wsgi.errors']

	if not db_basename in databases.databases:
		db_filename = os.path.join(environ["DATADIR"], db_basename)
		stderr.write("db_filename: %s\n" % db_filename)
		conn = sqlite3.connect(db_filename)
		conn.enable_load_extension(True)
		conn.load_extension("mod_spatialite")
		conn.enable_load_extension(False)
		conn.row_factory = sqlite3.Row
		databases.databases[db_basename] = (conn.cursor(), int(os.path.getmtime(db_filename)))
	(cursor, last_modified) = databases.databases[db_basename]

	time_now = time.time()
	response_headers = [
		('Date', formatdate(time_now, usegmt=True)),
        ('Last-Modified', formatdate(last_modified, usegmt=True)),
		('Cache-Control', 'public,max-age=86400'),
		]

	if_modified_since = environ.get("HTTP_IF_MODIFIED_SINCE")
	if if_modified_since is not None:
		stderr.write("If-Modified-Since: %s\n" % if_modified_since)
		stderr.write("Last-Modified: %s\n" % formatdate(last_modified, usegmt=True))
		if_modified_since = mktime_tz(parsedate_tz(if_modified_since))
		if last_modified <= if_modified_since:
			stderr.write("304 Not Modified\n")
			return (None, response_headers)

	return (cursor, response_headers)
Esempio n. 2
0
    def methodGetOrderList(
        self, count, page, status=None, transitionDateFrom=None, transitionDateTo=None, transitionStatus=None
    ):
        params = {}
        if not isinstance(count, int):
            raise ValueError("Argument 'count' must be integer")
        else:
            params["pageSize"] = count

        if not isinstance(page, int):
            raise ValueError("Argument 'page' must be integer")
        else:
            params["page"] = page
        validStatuses = ["opened", "canceled", "rejected", "confirmed", "annuled", "invalid", "faked"]
        if status is not None:
            if status not in validStatuses:
                raise ValueError("Valid values for argument 'status' is: " + ", ".join(validStatuses))
            else:
                params["status"] = status

        if transitionDateFrom != None:
            dtuple = transitionDateFrom.timetuple()
            dtimestamp = time.mktime(dtuple)
            params["transitionDateFrom"] = utils.formatdate(dtimestamp)

        if transitionDateTo != None:
            dtuple = transitionDateTo.timetuple()
            dtimestamp = time.mktime(dtuple)
            params["transitionDateFrom"] = utils.formatdate(dtimestamp)
        if transitionStatus != None:
            if transitionStatus not in validStatuses:
                raise ValueError("Valid values for argument 'transitionStatus' is: " + ", ".join(validStatuses))
            else:
                params["transitionStatus"] = transitionStatus
        return self._api("/api/1.0/orders?" + urllib.urlencode(params), self.METHOD_GET)
Esempio n. 3
0
 def wsgi_serve_static(self, path: str, environ: Dict[str, Any], start_response: WsgiStartResponseType) -> Iterable[bytes]:
     headers = []
     resource = vfs.internal_resources[path]
     if resource.mtime:
         mtime_formatted = formatdate(resource.mtime)
         etag = self.etag(id(vfs.internal_resources), resource.mtime, path)
         if_modified = environ.get('HTTP_IF_MODIFIED_SINCE')
         if if_modified:
             if parsedate(if_modified) >= parsedate(mtime_formatted):        # type: ignore
                 # the resource wasn't modified since last requested
                 return self.wsgi_not_modified(start_response)
         if_none = environ.get('HTTP_IF_NONE_MATCH')
         if if_none and (if_none == '*' or etag in if_none):
             return self.wsgi_not_modified(start_response)
         headers.append(("ETag", etag))
         headers.append(("Last-Modified", formatdate(resource.mtime)))
     if resource.is_text:
         # text
         headers.append(('Content-Type', resource.mimetype + "; charset=utf-8"))
         data = resource.text.encode("utf-8")
     else:
         # binary
         headers.append(('Content-Type', resource.mimetype))
         data = resource.data
     start_response('200 OK', headers)
     return [data]
Esempio n. 4
0
    def _get_blog_list(self, q, xml=False):

        self._curpage = int(self._req.par('p', default_value = 1))

        self._obj['data'] = []

        q.filter('ctype =', 'blog').order("-sortdate");

        if not self._req.sesh().can_edit():
            q.filter('status =', 'published')
        
        # fill in all our widgets        
        self._build_widgets_list(q.count(), q)

        # to stick in the rss
        newest = datetime.datetime.fromtimestamp(0)
        
        for c in q.fetch(self._PAGESIZE, offset=(self._curpage-1) * self._PAGESIZE):
            d = self.copy_bits(c)

            d.rssdate = emailutils.formatdate(time.mktime(c.sortdate.timetuple()), usegmt=True)
            
            self._obj['data'].append(d)

            if c.sortdate > newest:
                newest = c.sortdate

        # format in the rss standard format
        self._obj['rssrecentdate'] = emailutils.formatdate(time.mktime(newest.timetuple()), usegmt=True)
           
        self._respond(path='blog', obj=self._obj, xml=xml)
Esempio n. 5
0
 def wsgi_serve_static(self, path, environ, start_response):
     headers = []
     resource = vfs.internal_resources[path]
     if resource.mtime:
         # unfortunately, this is usually only present when running under python 3.x...
         mtime_formatted = formatdate(resource.mtime)
         etag = self.etag(id(vfs.internal_resources), resource.mtime, path)
         if_modified = environ.get("HTTP_IF_MODIFIED_SINCE")
         if if_modified:
             if parsedate(if_modified) >= parsedate(mtime_formatted):
                 # the resource wasn't modified since last requested
                 return self.wsgi_not_modified(start_response)
         if_none = environ.get("HTTP_IF_NONE_MATCH")
         if if_none and (if_none == "*" or etag in if_none):
             return self.wsgi_not_modified(start_response)
         headers.append(("ETag", etag))
         headers.append(("Last-Modified", formatdate(resource.mtime)))
     if type(resource.data) is bytes:
         headers.append(("Content-Type", resource.mimetype))
         data = resource.data
     else:
         headers.append(("Content-Type", resource.mimetype + "; charset=utf-8"))
         data = resource.data.encode("utf-8")
     start_response("200 OK", headers)
     return [data]
Esempio n. 6
0
def create_email(frm=None, to=None, cc=None, bcc=None, subject=None, text=None, html=None, date=None, reply_to=None, attachments=[]):
    msg = MIMEMultipart('alternative')
    if frm:
        msg["From"] = frm
    if to:
        msg["To"] = to
    if cc:
        msg["Cc"] = cc
    if bcc:
        msg["Bcc"] = bcc
    if subject:
        msg["Subject"] = subject
    if text:
        textmsg = MIMEText(text, 'plain', _charset='utf-8')
        msg.attach(textmsg)
    if html:
        htmlmsg = MIMEText(html, 'html', _charset='utf-8')
        msg.attach(htmlmsg)
    if date is None:
        msg["Date"] = formatdate(localtime=True)
    else:
        msg["Date"] = formatdate(date, localtime=True)
    if reply_to:
        msg["Reply-To"] = reply_to
    for attachment in attachments:
        msg.attach(attachment)
    return msg
Esempio n. 7
0
def feed(request):
    channel_data = get_channel_data()

    channel = dict()
    channel['id'] = channel_data['id']
    channel['title'] = channel_data['snippet']['title']
    channel['description'] = channel_data['snippet']['description']
    channel['logo'] = channel_data['snippet']['thumbnails']['default']['url']

    feed = dict()
    feed['build'] = formatdate(time.mktime(datetime.now().timetuple()))
    feed['baseurl'] = config.get_option(u'SITE_URL')

    video_list = get_all_public_video_data(channel['id'])

    items = list()
    for v in video_list:
        item = dict()
        item['id'] = v['id']
        item['title'] = v['snippet']['title']
        item['description'] = v['snippet']['description']
        published_at = datetime.strptime(v['snippet']['publishedAt'], "%Y-%m-%dT%H:%M:%S.000Z")
        item['published'] = dict()
        item['published']['short'] = published_at.date().isoformat()
        item['published']['long'] = formatdate(time.mktime(published_at.timetuple()))
        item['thumbnail'] = v['snippet']['thumbnails']['high']
        item['category'] = v['snippet']['tags'][-1]
        if 'tags' in item:
            item['tags'] = u','.join(v['snippet']['tags'][:-1])

        items.append(item)

    return render_to_response("yt_publisher/yt-feed.html", { 'channel' :  channel, 'feed' : feed, 'items' : items }, context_instance=RequestContext(request))
Esempio n. 8
0
    def setUp(self):
        self.file_type = "text/html"
        self.file_body = "<!DOCTYPE html>\n<html>\n<body>\n\n<h1>North Carolina</h1>\n\n<p>A fine place to spend a week learning web programming!</p>\n\n</body>\n</html>\n\n"
        self.file_response = "HTTP/1.1 200 OK\r\nDate: " + formatdate(usegmt=True) + "\r\nContent-Type: text/html; Character-Type: UTF-8\r\nContent-Length: 136\r\n\r\n<!DOCTYPE html>\n<html>\n<body>\n\n<h1>North Carolina</h1>\n\n<p>A fine place to spend a week learning web programming!</p>\n\n</body>\n</html>\n\n"

        self.dir_type = "text/plain"
        self.dir_body = "/images\r\n\tJPEG_example.jpg\r\n\tSample_Scene_Balls.jpg\r\n\tsample_1.png"
        self.dir_response = "HTTP/1.1 200 OK\r\nDate: " + formatdate(usegmt=True) + "\r\nContent-Type: text/plain; Character-Type: UTF-8\r\nContent-Length: 66\r\n\r\n/images\r\n\tJPEG_example.jpg\r\n\tSample_Scene_Balls.jpg\r\n\tsample_1.png"
Esempio n. 9
0
 def test_formatdate_with_localtime(self):
     timeval = time.mktime((2011, 1, 1, 18, 0, 0, 6, 1, 0))
     string = utils.formatdate(timeval, localtime=True)
     self.assertEqual(string, 'Sat, 01 Jan 2011 18:00:00 +0200')
     # Minsk moved from +0200 (with DST) to +0300 (without DST) in 2011
     timeval = time.mktime((2011, 12, 1, 18, 0, 0, 4, 335, 0))
     string = utils.formatdate(timeval, localtime=True)
     self.assertEqual(string, 'Thu, 01 Dec 2011 18:00:00 +0300')
Esempio n. 10
0
    def handle_GET(self, request, context, hash):
        gm = get_object_or_404(GeneratedMap, hash=hash)
        response = HttpResponse(open(gm.get_filename(), 'r').read(), mimetype='image/png')

        response['Expires'] = formatdate(mktime((datetime.now() + timedelta(days=7)).timetuple()))
        response['Last-Modified'] = formatdate(mktime(gm.generated.timetuple()))
        response['ETag'] = hash
        return response
Esempio n. 11
0
    def handle_GET(self, request, context, slug):
        eis = get_object_or_404(ExternalImageSized, slug=slug)
        response = HttpResponse(open(eis.get_filename(), 'r').read(), mimetype=eis.content_type.encode('ascii'))

        response['ETag'] = slug
        response['Expires'] = formatdate(mktime((datetime.now() + timedelta(days=7)).timetuple()))
        response['Last-Modified'] = formatdate(mktime(eis.external_image.last_updated.timetuple()))
        return response
Esempio n. 12
0
    def default(self, obj):
        if isinstance(obj, datetime):
            return formatdate(timegm(obj.utctimetuple()), usegmt=True)

        if isinstance(obj, date):
            _obj = datetime.combine(obj, datetime.min.time())
            return formatdate(timegm(_obj.utctimetuple()), usegmt=True)

        return json.JSONEncoder.default(self, obj)
Esempio n. 13
0
def _modified(last_modified, handler):
    ims_value = handler.request.headers.get("If-Modified-Since")
    if ims_value is not None:
        date_tuple = email.utils.parsedate(ims_value)
        if_since = datetime.fromtimestamp(time.mktime(date_tuple))
        # print 'about to compare', if_since, datetime.fromtimestamp(last_modified)
        if if_since >= datetime.fromtimestamp(last_modified):
            raise Send304Exception()
    handler.set_header("Date", formatdate(timeval = time.time(), localtime = False, usegmt = True))
    handler.set_header('Last-Modified', formatdate(timeval = last_modified, localtime = False, usegmt = True))
Esempio n. 14
0
def format_date_header(v, localtime=True):
    if isinstance(v, datetime):
        return formatdate(mktime(v.timetuple()), localtime)
    elif isinstance(v, float):
        # probably timestamp
        return formatdate(v, localtime)
    elif v is None:
        return formatdate(None, localtime)
    else:
        return v
Esempio n. 15
0
def shiftdate():
    """Only sends from 9:00 till 18:00"""
    # formatdate(timeval=None, localtime=False, usegmt=False)
    # Thu, 05 Jul 2012 22:11:35 +0400
    realDate = formatdate(localtime=True)

    # 22
    realHour = realDate[-14:-12]
    # formatedate() returns a string.
    realHour = int(realHour)

    if realHour >= 9 and realHour <= 17:
        return realDate

    elif realHour >= 18 and realHour <= 23:
        start = realHour.__sub__(17)
        end = realHour.__sub__(9)
        # Real hour is shifted `shift' hours back.
        shift = randint(start, end)
        # Method 1. String substitution.
        shiftedHour = realHour - shift
        shiftedHour = shiftedHour.__str__()
        # 09
        shiftedHour = shiftedHour.zfill(2)
        # Thu, 05 Jul 2012 09:31:28 +0400
        shiftedDate = (
            # Thu, 05 Jul 2012
            realDate[0:-14]
            +
            # 09
            shiftedHour
            +
            #:31:28 +0400
            realDate[-12:]
        )

        # Method 2. - 60 * 60 * shift
        # Thu, 05 Jul 2012 10:37:42 +0400
        # Thu, 05 Jul 2012 10:37:42 +0400
        shiftedDate = formatdate(time.time() - 60 * 60 * shift, localtime=True)
        return shiftedDate

    elif realHour >= 0 and realHour <= 8:
        # 24 - 17 = 7
        # 08:mm -> 00:mm -> 17:mm
        start = 7 + realHour
        # 24 - 9 = 15
        # 08:mm -> 00:mm -> 09:mm
        end = 15 + realHour
        # Real hour is shifted `shift' hours back.
        shift = randint(start, end)
        # timeval = time.time() - 60 * 60 * shif
        shiftedDate = formatdate(time.time() - 60 * 60 * shift, localtime=True)
        return shiftedDate
def create_timestamp(dt = None):
    # "local_time_rfc822":"Tue, 23 Sep 2014 18:19:54 -0700"
    if dt == None:
        nowdt = datetime.datetime.now()
    else:
        nowdt = dt
        
    nowtuple = nowdt.timetuple()
    nowtimestamp = time.mktime(nowtuple)
    utils.formatdate(nowtimestamp)
    return utils.formatdate(nowtimestamp)
Esempio n. 17
0
def test_can_ignore_email_module():
    from email.utils import formatdate
    with freeze_time('2012-01-14'):
        faked_date_str = formatdate()

    before_date_str = formatdate()
    with freeze_time('2012-01-14', ignore=['email']):
        date_str = formatdate()

    after_date_str = formatdate()
    assert date_str != faked_date_str
    assert before_date_str <= date_str <= after_date_str
Esempio n. 18
0
    def method_get_order_list(self, count, page, status=None, transition_date_from=None, transition_date_to=None,
                              transition_status=None):
        """
        Получение списка заказов
        :param count:                Количество возвращаемых заказов на "странице"
        :type count: int
        :param page:                 Порядковый номер "страницы", начиная с 1
        :type page
        :param status:               Фильтр по статусам. Допустимые значения:
                                     opened, canceled, rejected, confirmed, anulled, invalid, faked
        :type status: str or None
        :param transition_date_from: Начало диапазона времени изменения статуса заказа
        :type transition_date_from:  datetime or None
        :param transition_date_to:   Конец диапозона времени изменения статуса заказа
        :type transition_date_to:    datetime or None
        :param transition_status:    Статус заказа, который был присвоен в указанный период времени
        :type transition_status:     str or None
        :rtype: Response
        :raise: ValueError
        """
        params = {}
        if not isinstance(count, int):
            raise ValueError('Argument \'%s\' must be integer' % count)
        else:
            params['pageSize'] = count

        if not isinstance(page, int):
            raise ValueError('Argument \'%s\' must be integer' % count)
        else:
            params['page'] = page

        if status is not None:
            if status not in self._valid_statuses:
                raise ValueError(('Valid values for argument \'%s\' is: ' % status) + ', '.join(self._valid_statuses))
            else:
                params['status'] = status

        if transition_date_from is not None:
            dtuple = transition_date_from.timetuple()
            dtimestamp = time.mktime(dtuple)
            params['transitionDateFrom'] = utils.formatdate(dtimestamp)

        if transition_date_to is not None:
            dtuple = transition_date_to.timetuple()
            dtimestamp = time.mktime(dtuple)
            params['transitionDateFrom'] = utils.formatdate(dtimestamp)
        if transition_status is not None:
            if transition_status not in self._valid_statuses:
                raise ValueError(('Valid values for argument \'%s\' is: ' % transition_status) + ', '.join(self._valid_statuses))
            else:
                params['transitionStatus'] = transition_status
        return self._api(self.API_PATH + "orders?" + urlencode(params), self.METHOD_GET)
Esempio n. 19
0
def SendMail1(From,Subject,Bodytekst,Attach,SMTPServer,To):
    msg = MIMEMultipart() #create a new mime multipart message
    msg["From"] = From #Default from
    msg["Subject"] = Subject #Later vervangen door subject uit input
    msg["Date"] = formatdate(localtime=True) #voeg de datum toe
    msg["To"] = To.Email #To address
    msg.preamble = 'Your mail program is NOT MIME aware!'
    GenerateAttachment(Bodytekst,msg,Attach)
    if not DEBUG :
        SendMailToServer(SMTPServer,'leo','tux001',From,To.Email,b(msg.as_string()))
    #Output-string, to be shown in GUI-window
    output = formatdate(localtime=True)+'> Mail verzonden naar: '+To.Naam+' <'+To.Email+'>'
    return output
	def addResponseBodyHeaders(self, resbody):
			if self.code == "200":
				print str(os.path.getsize(self.path))
				extension = os.path.splitext(self.path)[1]
				self.headers["Content-Type"] = self.config.medias[extension[1:]]
				self.headers["Last-Modified"] = formatdate(os.stat(self.path).st_mtime, localtime=False, usegmt=True)
				if not hasattr(self.request, 'lowerbound'):
					self.headers["Content-Length"] = str(os.path.getsize(self.path))
				else:
					self.headers["Content-Length"] = str((self.request.upperbound + 1) - self.request.lowerbound)
			else:
				self.headers["Content-Type"] = self.config.medias["html"]
				self.headers["Content-Length"] = str(len(resbody))
				self.headers["Last-Modified"] = formatdate(time.time(), localtime=False, usegmt=True) 
    def test_FileResource_GET_if_modified_since(self):
        #Test If-Modified-Since header support

        factory = FileResourceFactory(self.testFilePath, self.nullChecker, 'test.txt')

        timestamp = time.time()

        file = factory._FileResourceFactory__file # get mangled file
        file.lmt = timestamp
        file.lmh = formatdate(timestamp, usegmt=True)

        before = timestamp - 1000
        request = TestRequest(HTTP_IF_MODIFIED_SINCE=formatdate(before, usegmt=True))
        resource = factory(request)
        self.assertTrue(resource.GET())

        after = timestamp + 1000
        request = TestRequest(HTTP_IF_MODIFIED_SINCE=formatdate(after, usegmt=True))
        resource = factory(request)
        self.assertFalse(resource.GET())

        self.assertEqual(request.response.getStatus(),
                         304)

        # Cache control headers and ETag are set on 304 responses

        self.assertEqual(request.response.getHeader('ETag'),
                         '"myetag"')
        self.assertEqual(request.response.getHeader('Cache-Control'),
                         'public,max-age=86400')
        self.assertTrue(request.response.getHeader('Expires'))

        # Other entity headers are not

        self.assertIsNone(request.response.getHeader('Last-Modified'))
        self.assertIsNone(request.response.getHeader('Content-Type'))

        # It won't fail on bad If-Modified-Since headers.

        request = TestRequest(HTTP_IF_MODIFIED_SINCE='bad header')
        resource = factory(request)
        self.assertTrue(resource.GET())

        # it also won't fail if we don't have a last modification time for the
        # resource

        file.lmt = None
        request = TestRequest(HTTP_IF_MODIFIED_SINCE=formatdate(after, usegmt=True))
        resource = factory(request)
        self.assertTrue(resource.GET())
Esempio n. 22
0
def send_mail(send_from, send_to, subject, text, filename=None):
    msg = emm.MIMEMultipart()
    msg['From'] = send_from
    msg['To'] = send_to
    msg['Date'] = eu.formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach(emt.MIMEText(text))

    # Attach the given file.
    if filename is not None:
        with open(filename, "rb") as f:
            part = ema.MIMEApplication(f.read(), Name=os.path.basename(f))

        part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
        msg.attach(part)

    # Get the recipient MX record.
    domain = send_to.split('@')[1]
    server = get_mx_record(domain)
    smtp = smtplib.SMTP(server)

    # Send
    smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.close()
Esempio n. 23
0
    def emit(self, record):
        """
        Emit a record.

        Format the record and send it to the specified addressees.
        """
        try:
            import smtplib
            from email.utils import formatdate

            port = self.mailport
            if not port:
                port = smtplib.SMTP_PORT
            smtp = smtplib.SMTP(self.mailhost, port)
            msg = self.format(record)
            msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
                self.fromaddr,
                ",".join(self.toaddrs),
                self.getSubject(record),
                formatdate(),
                msg,
            )
            if self.username:
                if self.secure is not None:
                    smtp.ehlo()
                    smtp.starttls(*self.secure)
                    smtp.ehlo()
                smtp.login(self.username, self.password)
            smtp.sendmail(self.fromaddr, self.toaddrs, msg)
            smtp.quit()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)
Esempio n. 24
0
    def _mail_missing_message(self, subject, text):
        # FIXME: This should be handled properly via the event api
        # we should send a missing message on the mq, and let any reporter
        # handle that

        # first, see if we have a MailNotifier we can use. This gives us a
        # fromaddr and a relayhost.
        buildmaster = self.botmaster.master
        for st in buildmaster.services:
            if isinstance(st, MailNotifier):
                break
        else:
            # if not, they get a default MailNotifier, which always uses SMTP
            # to localhost and uses a dummy fromaddr of "buildbot".
            log.msg("worker-missing msg using default MailNotifier")
            st = MailNotifier("buildbot")
        # now construct the mail

        m = Message()
        m.set_payload(text)
        m['Date'] = formatdate(localtime=True)
        m['Subject'] = subject
        m['From'] = st.fromaddr
        recipients = self.notify_on_missing
        m['To'] = ", ".join(recipients)
        d = st.sendMessage(m, recipients)
        # return the Deferred for testing purposes
        return d
Esempio n. 25
0
    def process_response(self, request, response, spider):
        if request.meta.get('dont_cache', False):
            return response

        # Skip cached responses and uncacheable requests
        if 'cached' in response.flags or '_dont_cache' in request.meta:
            request.meta.pop('_dont_cache', None)
            return response

        # RFC2616 requires origin server to set Date header,
        # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.18
        if 'Date' not in response.headers:
            response.headers['Date'] = formatdate(usegmt=1)

        # Do not validate first-hand responses
        cachedresponse = request.meta.pop('cached_response', None)
        if cachedresponse is None:
            self.stats.inc_value('httpcache/firsthand', spider=spider)
            self._cache_response(spider, response, request, cachedresponse)
            return response

        if self.policy.is_cached_response_valid(cachedresponse, response, request):
            self.stats.inc_value('httpcache/revalidate', spider=spider)
            return cachedresponse

        self.stats.inc_value('httpcache/invalidate', spider=spider)
        self._cache_response(spider, response, request, cachedresponse)
        return response
def send_mail(_from_, to_, subject, text, files=None, server=config.MAIL_SERVER, port=config.MAIL_SERVER_PORT):
    assert isinstance(to_, (list, tuple))

    if files is None:
        files = []

    msg = MIMEMultipart()
    msg['From'] = _from_
    msg['To'] = COMMASPACE.join(to_)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach( MIMEText(text) )

    for file_name, file_content in files:
        part = MIMEBase('application', "octet-stream")
        part.set_payload( file_content )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"'
                       % file_name)
        msg.attach(part)

    smtp = smtplib.SMTP(server, port=port)
    smtp.sendmail(_from_, to_, msg.as_string() )
    smtp.close()
Esempio n. 27
0
    def _serialize_date(self, value):
        """
        Serialize a date into an RFC 2822-compliant binary string.
        """
        # If we're given a string, we return it as-is.
        if isinstance(value, binary_type):
            return value
        if isinstance(value, text_type):
            return value.encode('latin-1')

        # If we're given a time delta, we assume it's from now.
        if isinstance(value, timedelta):
            value = self.__now() + value

        # If we have a date/datetime, we make it into a tuple.
        if isinstance(value, (date, datetime)):
            value = value.timetuple()

        # Now, if we have a tuple of some sort, convert to an int.
        if isinstance(value, (tuple, time.struct_time)):
            value = calendar.timegm(value)

        # Finally, assert that we actually have an number by this point.
        if not isinstance(value, Number):
            logger.error("Unknown value to serialize: %r", value)
            raise ValueError("Unknown value to serialize: {0!r}".format(value))

        # Note: The 'usegmt' argument will put 'GMT' after the date, instead of
        # the string '-0000'.
        serialized = formatdate(value, usegmt=True)
        return serialized.encode('latin-1')
def TcpProbeThread():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Socket created")
 
    #Bind socket to local host and port
    try:
        s.bind((hostToListenTo, portToListenTo))
    except socket.error as msg:
        print("Bind failed. Error Code : " + str(msg[0]) + " Message " + msg[1])
        sys.exit()
    print("Socket bind complete")
    while 1:
        try:
            s.listen(10)
            print("Socket now listening...")
            conn, addr = s.accept()
            print("New TCP connection accepted.")
            headers = "Date: " + formatdate(timeval=None, localtime=False, usegmt=True) + "\nContent-Type: text/html\nContent-Length: 13\n\n<html></html>\n"
            if (isPrimary):
                print("Sending HTTP/1.1 200 OK")
                s.send("HTTP/1.1 200 OK\n" + headers)
                print ("Sent.")
            else:
                print("Sending HTTP/1.1 503 Service Unavailable")
                s.send("HTTP/1.1 503 Service Unavailable\n" + headers)
                print ("Sent.")
            print("Connected with " + addr[0] + ":" + str(addr[1]))
            s.close()
        except Exception as e:
            print ("Error in TcpProbeThread: " + e)
Esempio n. 29
0
def database(timestamp, channel, epg, out_file):

    rec_date = datetime.datetime.fromtimestamp(
        int(timestamp)).strftime('%Y.%m.%d')
    rec_time = datetime.datetime.fromtimestamp(
        int(timestamp)).strftime('%H:%M')
    pubdate = formatdate(time.time(), True)
    title = epg[1]
    if epg[2] == '':
        description = epg[3]
    else:
        description = epg[2] + '\n\n' + epg[3]
    audiofile = os.path.basename(out_file)
    length, length_bytes = audiolength(out_file)

    with closing(MySQLdb.connect(
            login.DB_HOST, login.DB_USER,
            login.DB_PASSWORD, login.DB_DATABASE)) as connection:
        with closing(connection.cursor()) as cursor:

            cursor.execute('INSERT INTO recordings \
            (date, time, channel, title, description, audiofile, timestamp, \
            length, bytes, pubdate) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)',
                    (rec_date, rec_time, channel, title, description,
                     audiofile, timestamp, length, length_bytes, pubdate))

            connection.commit()
Esempio n. 30
0
    def _get_cookies(self, environ, value, max_age=None):
        if max_age is not None:
            max_age = int(max_age)
            later = _now() + datetime.timedelta(seconds=max_age)
            # Wdy, DD-Mon-YY HH:MM:SS GMT
            expires = formatdate(timegm(later.timetuple()), usegmt=True)
            # the Expires header is *required* at least for IE7 (IE7 does
            # not respect Max-Age)
            max_age = "; Max-Age=%s; Expires=%s" % (max_age, expires)
        else:
            max_age = ''

        secure = ''
        if self.secure:
            secure = '; secure; HttpOnly'

        cur_domain = environ.get('HTTP_HOST', environ.get('SERVER_NAME'))
        cur_domain = cur_domain.split(':')[0] # drop port
        wild_domain = '.' + cur_domain
        cookies = [
            ('Set-Cookie', '%s="%s"; Path=/%s%s' % (
            self.cookie_name, value, max_age, secure)),
            ('Set-Cookie', '%s="%s"; Path=/; Domain=%s%s%s' % (
            self.cookie_name, value, cur_domain, max_age, secure)),
            ('Set-Cookie', '%s="%s"; Path=/; Domain=%s%s%s' % (
            self.cookie_name, value, wild_domain, max_age, secure))
            ]
        return cookies
Esempio n. 31
0
def request_date():
    return formatdate(timeval=None, localtime=False, usegmt=True)
Esempio n. 32
0
def email(ui, repo, *revs, **opts):
    '''send changesets by email

    By default, diffs are sent in the format generated by
    :hg:`export`, one per message. The series starts with a "[PATCH 0
    of N]" introduction, which describes the series as a whole.

    Each patch email has a Subject line of "[PATCH M of N] ...", using
    the first line of the changeset description as the subject text.
    The message contains two or three parts. First, the changeset
    description.

    With the -d/--diffstat option, if the diffstat program is
    installed, the result of running diffstat on the patch is inserted.

    Finally, the patch itself, as generated by :hg:`export`.

    With the -d/--diffstat or --confirm options, you will be presented
    with a final summary of all messages and asked for confirmation before
    the messages are sent.

    By default the patch is included as text in the email body for
    easy reviewing. Using the -a/--attach option will instead create
    an attachment for the patch. With -i/--inline an inline attachment
    will be created. You can include a patch both as text in the email
    body and as a regular or an inline attachment by combining the
    -a/--attach or -i/--inline with the --body option.

    With -B/--bookmark changesets reachable by the given bookmark are
    selected.

    With -o/--outgoing, emails will be generated for patches not found
    in the destination repository (or only those which are ancestors
    of the specified revisions if any are provided)

    With -b/--bundle, changesets are selected as for --outgoing, but a
    single email containing a binary Mercurial bundle as an attachment
    will be sent. Use the ``patchbomb.bundletype`` config option to
    control the bundle type as with :hg:`bundle --type`.

    With -m/--mbox, instead of previewing each patchbomb message in a
    pager or sending the messages directly, it will create a UNIX
    mailbox file with the patch emails. This mailbox file can be
    previewed with any mail user agent which supports UNIX mbox
    files.

    With -n/--test, all steps will run, but mail will not be sent.
    You will be prompted for an email recipient address, a subject and
    an introductory message describing the patches of your patchbomb.
    Then when all is done, patchbomb messages are displayed.

    In case email sending fails, you will find a backup of your series
    introductory message in ``.hg/last-email.txt``.

    The default behavior of this command can be customized through
    configuration. (See :hg:`help patchbomb` for details)

    Examples::

      hg email -r 3000          # send patch 3000 only
      hg email -r 3000 -r 3001  # send patches 3000 and 3001
      hg email -r 3000:3005     # send patches 3000 through 3005
      hg email 3000             # send patch 3000 (deprecated)

      hg email -o               # send all patches not in default
      hg email -o DEST          # send all patches not in DEST
      hg email -o -r 3000       # send all ancestors of 3000 not in default
      hg email -o -r 3000 DEST  # send all ancestors of 3000 not in DEST

      hg email -B feature       # send all ancestors of feature bookmark

      hg email -b               # send bundle of all patches not in default
      hg email -b DEST          # send bundle of all patches not in DEST
      hg email -b -r 3000       # bundle of all ancestors of 3000 not in default
      hg email -b -r 3000 DEST  # bundle of all ancestors of 3000 not in DEST

      hg email -o -m mbox &&    # generate an mbox file...
        mutt -R -f mbox         # ... and view it with mutt
      hg email -o -m mbox &&    # generate an mbox file ...
        formail -s sendmail \\   # ... and use formail to send from the mbox
          -bm -t < mbox         # ... using sendmail

    Before using this command, you will need to enable email in your
    hgrc. See the [email] section in hgrc(5) for details.
    '''
    opts = pycompat.byteskwargs(opts)

    _charsets = mail._charsets(ui)

    bundle = opts.get('bundle')
    date = opts.get('date')
    mbox = opts.get('mbox')
    outgoing = opts.get('outgoing')
    rev = opts.get('rev')
    bookmark = opts.get('bookmark')

    if not (opts.get('test') or mbox):
        # really sending
        mail.validateconfig(ui)

    if not (revs or rev or outgoing or bundle or bookmark):
        raise error.Abort(
            _('specify at least one changeset with -B, -r or -o'))

    if outgoing and bundle:
        raise error.Abort(
            _("--outgoing mode always on with --bundle;"
              " do not re-specify --outgoing"))
    if rev and bookmark:
        raise error.Abort(_("-r and -B are mutually exclusive"))

    if outgoing or bundle:
        if len(revs) > 1:
            raise error.Abort(_("too many destinations"))
        if revs:
            dest = revs[0]
        else:
            dest = None
        revs = []

    if rev:
        if revs:
            raise error.Abort(_('use only one form to specify the revision'))
        revs = rev
    elif bookmark:
        if bookmark not in repo._bookmarks:
            raise error.Abort(_("bookmark '%s' not found") % bookmark)
        revs = scmutil.bookmarkrevs(repo, bookmark)

    revs = scmutil.revrange(repo, revs)
    if outgoing:
        revs = _getoutgoing(repo, dest, revs)
    if bundle:
        opts['revs'] = ["%d" % r for r in revs]

    # check if revision exist on the public destination
    publicurl = repo.ui.config('patchbomb', 'publicurl')
    if publicurl:
        repo.ui.debug('checking that revision exist in the public repo\n')
        try:
            publicpeer = hg.peer(repo, {}, publicurl)
        except error.RepoError:
            repo.ui.write_err(
                _('unable to access public repo: %s\n') % publicurl)
            raise
        if not publicpeer.capable('known'):
            repo.ui.debug('skipping existence checks: public repo too old\n')
        else:
            out = [repo[r] for r in revs]
            known = publicpeer.known(h.node() for h in out)
            missing = []
            for idx, h in enumerate(out):
                if not known[idx]:
                    missing.append(h)
            if missing:
                if len(missing) > 1:
                    msg = _('public "%s" is missing %s and %i others')
                    msg %= (publicurl, missing[0], len(missing) - 1)
                else:
                    msg = _('public url %s is missing %s')
                    msg %= (publicurl, missing[0])
                missingrevs = [ctx.rev() for ctx in missing]
                revhint = ' '.join(
                    '-r %s' % h for h in repo.set('heads(%ld)', missingrevs))
                hint = _("use 'hg push %s %s'") % (publicurl, revhint)
                raise error.Abort(msg, hint=hint)

    # start
    if date:
        start_time = dateutil.parsedate(date)
    else:
        start_time = dateutil.makedate()

    def genmsgid(id):
        return _msgid(id[:20], int(start_time[0]))

    # deprecated config: patchbomb.from
    sender = (opts.get('from') or ui.config('email', 'from')
              or ui.config('patchbomb', 'from')
              or prompt(ui, 'From', ui.username()))

    if bundle:
        stropts = pycompat.strkwargs(opts)
        bundledata = _getbundle(repo, dest, **stropts)
        bundleopts = stropts.copy()
        bundleopts.pop(r'bundle', None)  # already processed
        msgs = _getbundlemsgs(repo, sender, bundledata, **bundleopts)
    else:
        msgs = _getpatchmsgs(repo, sender, revs, **pycompat.strkwargs(opts))

    showaddrs = []

    def getaddrs(header, ask=False, default=None):
        configkey = header.lower()
        opt = header.replace('-', '_').lower()
        addrs = opts.get(opt)
        if addrs:
            showaddrs.append('%s: %s' % (header, ', '.join(addrs)))
            return mail.addrlistencode(ui, addrs, _charsets, opts.get('test'))

        # not on the command line: fallback to config and then maybe ask
        addr = (ui.config('email', configkey)
                or ui.config('patchbomb', configkey))
        if not addr:
            specified = (ui.hasconfig('email', configkey)
                         or ui.hasconfig('patchbomb', configkey))
            if not specified and ask:
                addr = prompt(ui, header, default=default)
        if addr:
            showaddrs.append('%s: %s' % (header, addr))
            return mail.addrlistencode(ui, [addr], _charsets, opts.get('test'))
        elif default:
            return mail.addrlistencode(ui, [default], _charsets,
                                       opts.get('test'))
        return []

    to = getaddrs('To', ask=True)
    if not to:
        # we can get here in non-interactive mode
        raise error.Abort(_('no recipient addresses provided'))
    cc = getaddrs('Cc', ask=True, default='')
    bcc = getaddrs('Bcc')
    replyto = getaddrs('Reply-To')

    confirm = ui.configbool('patchbomb', 'confirm')
    confirm |= bool(opts.get('diffstat') or opts.get('confirm'))

    if confirm:
        ui.write(_('\nFinal summary:\n\n'), label='patchbomb.finalsummary')
        ui.write(('From: %s\n' % sender), label='patchbomb.from')
        for addr in showaddrs:
            ui.write('%s\n' % addr, label='patchbomb.to')
        for m, subj, ds in msgs:
            ui.write(('Subject: %s\n' % subj), label='patchbomb.subject')
            if ds:
                ui.write(ds, label='patchbomb.diffstats')
        ui.write('\n')
        if ui.promptchoice(
                _('are you sure you want to send (yn)?'
                  '$$ &Yes $$ &No')):
            raise error.Abort(_('patchbomb canceled'))

    ui.write('\n')

    parent = opts.get('in_reply_to') or None
    # angle brackets may be omitted, they're not semantically part of the msg-id
    if parent is not None:
        if not parent.startswith('<'):
            parent = '<' + parent
        if not parent.endswith('>'):
            parent += '>'

    sender_addr = eutil.parseaddr(encoding.strfromlocal(sender))[1]
    sender = mail.addressencode(ui, sender, _charsets, opts.get('test'))
    sendmail = None
    firstpatch = None
    progress = ui.makeprogress(_('sending'), unit=_('emails'), total=len(msgs))
    for i, (m, subj, ds) in enumerate(msgs):
        try:
            m['Message-Id'] = genmsgid(m['X-Mercurial-Node'])
            if not firstpatch:
                firstpatch = m['Message-Id']
            m['X-Mercurial-Series-Id'] = firstpatch
        except TypeError:
            m['Message-Id'] = genmsgid('patchbomb')
        if parent:
            m['In-Reply-To'] = parent
            m['References'] = parent
        if not parent or 'X-Mercurial-Node' not in m:
            parent = m['Message-Id']

        m['User-Agent'] = 'Mercurial-patchbomb/%s' % util.version()
        m['Date'] = eutil.formatdate(start_time[0], localtime=True)

        start_time = (start_time[0] + 1, start_time[1])
        m['From'] = sender
        m['To'] = ', '.join(to)
        if cc:
            m['Cc'] = ', '.join(cc)
        if bcc:
            m['Bcc'] = ', '.join(bcc)
        if replyto:
            m['Reply-To'] = ', '.join(replyto)
        # Fix up all headers to be native strings.
        # TODO(durin42): this should probably be cleaned up above in the future.
        if pycompat.ispy3:
            for hdr, val in list(m.items()):
                change = False
                if isinstance(hdr, bytes):
                    del m[hdr]
                    hdr = pycompat.strurl(hdr)
                    change = True
                if isinstance(val, bytes):
                    val = pycompat.strurl(val)
                    if not change:
                        # prevent duplicate headers
                        del m[hdr]
                    change = True
                if change:
                    m[hdr] = val
        if opts.get('test'):
            ui.status(_('displaying '), subj, ' ...\n')
            ui.pager('email')
            generator = _bytesgenerator(ui, mangle_from_=False)
            try:
                generator.flatten(m, 0)
                ui.write('\n')
            except IOError as inst:
                if inst.errno != errno.EPIPE:
                    raise
        else:
            if not sendmail:
                sendmail = mail.connect(ui, mbox=mbox)
            ui.status(_('sending '), subj, ' ...\n')
            progress.update(i, item=subj)
            if not mbox:
                # Exim does not remove the Bcc field
                del m['Bcc']
            fp = stringio()
            generator = _bytesgenerator(fp, mangle_from_=False)
            generator.flatten(m, 0)
            alldests = to + bcc + cc
            alldests = [encoding.strfromlocal(d) for d in alldests]
            sendmail(sender_addr, alldests, fp.getvalue())

    progress.complete()
Esempio n. 33
0
    def serve(self, fp, check, request_host):
        """
            fp: The file pointer to write to.

            check: A function called with the effective actions (after random
            values have been calculated). If it returns False service proceeds,
            otherwise the return is treated as an error message to be sent to
            the client, and service stops.

            request_host: If this a request, this is the connecting host. If
            None, we assume it's a response. Used to decide what standard
            modifications to make if raw is not set.

            Calling this function may modify the object.
        """
        started = time.time()
        if not self.raw:
            if self.body and not utils.get_header("Content-Length",
                                                  self.headers):
                self.headers.append((
                    LiteralGenerator("Content-Length"),
                    LiteralGenerator(str(len(self.body))),
                ))
            if request_host:
                if not utils.get_header("Host", self.headers):
                    self.headers.append((LiteralGenerator("Host"),
                                         LiteralGenerator(request_host)))

            else:
                if not utils.get_header("Date", self.headers):
                    self.headers.append((LiteralGenerator("Date"),
                                         LiteralGenerator(
                                             formatdate(timeval=None,
                                                        localtime=False,
                                                        usegmt=True))))

        hdrs = []
        for k, v in self.headers:
            hdrs.extend([
                k,
                ": ",
                v,
                "\r\n",
            ])
        vals = self.preamble()
        vals.append("\r\n")
        vals.extend(hdrs)
        vals.append("\r\n")
        if self.body:
            vals.append(self.body)
        vals.reverse()
        actions = ready_actions(self.length(), self.actions)
        actions.reverse()
        if check:
            ret = check(self, actions)
            if ret:
                err = PathodErrorResponse(ret)
                err.serve(fp)
                return dict(disconnect=True,
                            actions=actions_log(actions),
                            error=ret)
        disconnect = write_values(fp, vals, actions[:])
        duration = time.time() - started
        ret = dict(
            disconnect=disconnect,
            started=started,
            duration=duration,
            actions=actions_log(actions),
        )
        for i in self.logattrs:
            v = getattr(self, i)
            # Careful not to log any VALUE specs without sanitizing them first. We truncate at 1k.
            if hasattr(v, "__len__"):
                v = v[:TRUNCATE]
            ret[i] = v
        return ret
def http_time(time):
    """Formats a datetime as an RFC 1123 compliant string."""
    return formatdate(timeval=mktime(time.timetuple()), localtime=False, usegmt=True)
Esempio n. 35
0
def build_mime_message(
    mail_from: str,
    to: Union[str, Iterable[str]],
    subject: str,
    html_content: str,
    files: Optional[List[str]] = None,
    cc: Optional[Union[str, Iterable[str]]] = None,
    bcc: Optional[Union[str, Iterable[str]]] = None,
    mime_subtype: str = 'mixed',
    mime_charset: str = 'utf-8',
    custom_headers: Optional[Dict[str, Any]] = None,
) -> Tuple[MIMEMultipart, List[str]]:
    """
    Build a MIME message that can be used to send an email and
    returns full list of recipients.

    :param mail_from: Email address to set as email's from
    :param to: List of email addresses to set as email's to
    :param subject: Email's subject
    :param html_content: Content of email in HTML format
    :param files: List of paths of files to be attached
    :param cc: List of email addresses to set as email's CC
    :param bcc: List of email addresses to set as email's BCC
    :param mime_subtype: Can be used to specify the subtype of the message. Default = mixed
    :param mime_charset: Email's charset. Default = UTF-8.
    :param custom_headers: Additional headers to add to the MIME message.
        No validations are run on these values and they should be able to be encoded.
    :return: Email as MIMEMultipart and list of recipients' addresses.
    """
    to = get_email_address_list(to)

    msg = MIMEMultipart(mime_subtype)
    msg['Subject'] = subject
    msg['From'] = mail_from
    msg['To'] = ", ".join(to)
    recipients = to
    if cc:
        cc = get_email_address_list(cc)
        msg['CC'] = ", ".join(cc)
        recipients = recipients + cc

    if bcc:
        # don't add bcc in header
        bcc = get_email_address_list(bcc)
        recipients = recipients + bcc

    msg['Date'] = formatdate(localtime=True)
    mime_text = MIMEText(html_content, 'html', mime_charset)
    msg.attach(mime_text)

    for fname in files or []:
        basename = os.path.basename(fname)
        with open(fname, "rb") as file:
            part = MIMEApplication(file.read(), Name=basename)
            part['Content-Disposition'] = f'attachment; filename="{basename}"'
            part['Content-ID'] = f'<{basename}>'
            msg.attach(part)

    if custom_headers:
        for header_key, header_value in custom_headers.items():
            msg[header_key] = header_value

    return msg, recipients
Esempio n. 36
0
	gmail_addr = "*****@*****.**"		# 例)[email protected]
	gmail_pass = "******"	# 例)abc123xyz
	SMTP = "smtp.gmail.com"
	PORT = 587
		
	# 送信メール情報
	from_addr = gmail_addr				# 送信元メールアドレス(Gmailでなくてもよい)
	to_addr = "*****@*****.**"		# 例)[email protected]
	subject = "12:34 #CoffeeComplete"		# 件名
	body = ""	# 本文
	# メールメッセージを作成
	msg = MIMEText(body, "plain", "utf-8")	# ラズパイのpython3では3つの引数でエンコードをutf-8にしないと
						# 'ascii' codec can't encode characters in position 0-14: ordinal not in range(128) というエラーがでる
	msg["From"] = from_addr
	msg["To"] = to_addr
	msg["Date"] = formatdate()			# 日付をインターネットで送信できるフォーマットで指定
	msg["Subject"] = subject
		
	# メール送信
	try:
		print("メール送信中...")
		send = smtplib.SMTP(SMTP, PORT)		# GmailのSMTPを利用してSMTPオブジェクトを生成
		send.ehlo()
		send.starttls()
		send.ehlo()
		send.login(gmail_addr, gmail_pass)	# Gmailにログイン
		send.send_message(msg)			# メールを送信
		send.close()
	except Exception as e:
		print("except: " + str(e))		# エラー送出時のメッセージ表示
	else:
Esempio n. 37
0
    def generateExcel(self):
        # Create a Pandas Excel writer using XlsxWriter as the engine.\
        os.chdir('/tmp')
        writer = pd.ExcelWriter('cost_explorer_report.xlsx',
                                engine='xlsxwriter')
        workbook = writer.book
        for report in self.reports:
            print(report['Name'], report['Type'])
            report['Data'].to_excel(writer, sheet_name=report['Name'])
            worksheet = writer.sheets[report['Name']]
            if report['Type'] == 'chart':

                # Create a chart object.
                chart = workbook.add_chart({
                    'type': 'column',
                    'subtype': 'stacked'
                })

                chartend = 12
                if CURRENT_MONTH:
                    chartend = 13
                for row_num in range(1, len(report['Data']) + 1):
                    chart.add_series({
                        'name': [report['Name'], row_num, 0],
                        'categories': [report['Name'], 0, 1, 0, chartend],
                        'values':
                        [report['Name'], row_num, 1, row_num, chartend],
                    })
                chart.set_y_axis({'label_position': 'low'})
                chart.set_x_axis({'label_position': 'low'})
                worksheet.insert_chart('O2', chart, {
                    'x_scale': 2.0,
                    'y_scale': 2.0
                })
        writer.save()

        #Time to deliver the file to S3
        if os.environ.get('S3_BUCKET'):
            s3 = boto3.client('s3')
            s3.upload_file("cost_explorer_report.xlsx",
                           os.environ.get('S3_BUCKET'),
                           "cost_explorer_report.xlsx")
        if os.environ.get('SES_SEND'):
            #Email logic
            msg = MIMEMultipart()
            msg['From'] = os.environ.get('SES_FROM')
            msg['To'] = COMMASPACE.join(os.environ.get('SES_SEND').split(","))
            msg['Date'] = formatdate(localtime=True)
            msg['Subject'] = "Cost Explorer Report"
            text = "Find your Cost Explorer report attached\n\n"
            msg.attach(MIMEText(text))
            with open("cost_explorer_report.xlsx", "rb") as fil:
                part = MIMEApplication(fil.read(),
                                       Name="cost_explorer_report.xlsx")
            part[
                'Content-Disposition'] = 'attachment; filename="%s"' % "cost_explorer_report.xlsx"
            msg.attach(part)
            #SES Sending
            ses = boto3.client('ses', region_name=SES_REGION)
            result = ses.send_raw_email(
                Source=msg['From'],
                Destinations=os.environ.get('SES_SEND').split(","),
                RawMessage={'Data': msg.as_string()})
    def AfterProcess(self, ctx):
        pShots = ctx['items']
        subject = self.GetSubject(pShots, ctx)

        msg = MIMEMultipart('alternative')
        msg['From'] = self.sender
        msg['To'] = COMMASPACE.join(self.to)
        msg['Date'] = formatdate(localtime=True)
        msg['Subject'] = subject

        html = """
<html lang="en">
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"> -->
        <style>
html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}
/* html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0} */
html,body{font-family:Verdana,sans-serif;font-size:12px;line-height:1.5}html{overflow-x:hidden}
a{background-color:transparent}a:active,a:hover{outline-width:0}
.w3-container,.w3-panel{padding:0.03em 16px}
/* .w3-container:after,.w3-container:before,.w3-panel:after,.w3-panel:before,.w3-row:after,.w3-row:before,.w3-row-padding:after,.w3-row-padding:before, */

.w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important}
/* .w3-round-small{border-radius:2px} */
.w3-round,.w3-round-medium{border-radius:4px}
/* .w3-round-large{border-radius:8px}
.w3-round-xlarge{border-radius:16px}
.w3-round-xxlarge{border-radius:32px} */
/* .w3-cell-row:before,.w3-cell-row:after,.w3-clear:after,.w3-clear:before,.w3-bar:before,.w3-bar:after{content:"";display:table;clear:both} */
/* .w3-panel{margin-top:16px;margin-bottom:16px} */
.w3-blue,.w3-hover-blue:hover{color:#fff!important;background-color:#2196F3!important}
.w3-table,.w3-table-all{border-collapse:collapse;border-spacing:0;width:100%;display:table;margin-bottom: 4px}
/* .w3-table-all{border:1px solid #ccc} */
.w3-table td,.w3-table th,.w3-table-all td,.w3-table-all th{padding:1px 4px;display:table-cell;text-align:left;vertical-align:top}
.w3-table th:first-child,.w3-table td:first-child,.w3-table-all th:first-child,.w3-table-all td:first-child{padding-left:5px;}
/* .w3-border-0{border:0!important} */
.w3-border{border:1px solid #ccc!important;}
/* .w3-border-top{border-top:1px solid #ccc!important}
.w3-border-bottom{border-bottom:1px solid #ccc!important}
.w3-border-left{border-left:1px solid #ccc!important}
.w3-border-right{border-right:1px solid #ccc!important} */
/* .w3-bordered tr,.w3-table-all tr{border-bottom:1px solid #ddd}.w3-striped tbody tr:nth-child(even){background-color:#f1f1f1} */
/* .w3-table-all tr:nth-child(odd){background-color:#fff}.w3-table-all tr:nth-child(even){background-color:#f1f1f1} */
/* .w3-hoverable tbody tr:hover,.w3-ul.w3-hoverable li:hover{background-color:#ccc}.w3-centered tr th,.w3-centered tr td{text-align:center} */
.w3-card,.w3-card-2{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)}
.w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important}
.w3-light-green,.w3-hover-light-green:hover{color:#000!important;background-color:#8bc34a!important}
.w3-green,.w3-hover-green:hover{color:#fff!important;background-color:#4CAF50!important}
.nowrap{white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}
.nowrap:hover{overflow: visible;}
/* .w3-card-4,.w3-hover-shadow:hover{box-shadow:0 4px 10px 0 rgba(0,0,0,0.2),0 4px 20px 0 rgba(0,0,0,0.19)} */
        </style>
    </head>
    <body>
   <!-- 🚶� # &#128540; # &#x1F6B6; -->
    <div class="w3-container">    
        """
        html += self.helper.MapToHtmlEmojiText(self.GetYoloLabels(ctx))

        for pShot in pShots or []:
            f = pShot.Shot.fullname

            dt = pShot.Shot.GetDatetime()
            idSource = pShot.Shot.GetId(self.config.camera)
            #self.log.debug(f'Encode: {idSource}')
            id = self.helper.Encode(idSource)

            html += f"""
            {self.GetBodyHtml(pShot)}
            <img src="http://{self.secretConfig.camera_tools_host}/image?id={id}"><br>
            | <a target="_blank" href="http://{self.secretConfig.camera_tools_host}/image?id={id}&original=1">Original</a> |
            <br>
            """

            # html += f"""
            # {self.GetBodyHtml(pShot)}
            # <img src="cid:{pShot.Shot.filename}"><br>
            # """

        html += "</div></body></html>"
        # part1 = MIMEText(body, 'plain')
        #msg.attach(part1)
        part2 = MIMEText(html, 'html')
        msg.attach(part2)

        meta0 = self.CreateMetadata(pShots[0])
        self.log.debug(f"- Send mail: '{subject}' to {self.to}")
        if not self.isSimulation:
            smtp = smtplib.SMTP('smtp.gmail.com', 587)
            smtp.starttls()
            smtp.login(self.secretConfig.gmail_username, self.secretConfig.gmail_password)
            smtp.sendmail(self.sender, self.to, msg.as_string())
            smtp.quit() 
            smtp.close()
        else:
            meta0['html'] = html
            meta0['id'] = idSource

        meta0["Subject"] = subject
        meta0["MessageSize"] = len(msg.as_string())
        return pShots