源码阅读学习笔记-kennethreitz/envoy:Python Subprocesses for Humans™.

通过python 执行shell命令 对人友好的方式;

学习总结:
1、下划线用法,区别
2、上下文管理器
3、特性、属性 以及学会使用装饰器方式实现的属性
# -*- coding: utf-8 -*-

"""
envoy.core
~~~~~~~~~~
This module provides envoy awesomeness.
"""

import os
import sys
import shlex   #模块实现了一个类来解析简单的类shell语法,可以用来编写领域特定的语言,或者解析加引号的字符串
import signal
import subprocess
import threading
import traceback #模块允许你在程序里打印异常的跟踪返回


__version__ = '0.0.3'
__license__ = 'MIT'
__author__ = 'Kenneth Reitz'   
#__ _ 下划线说明
# _var 在一个模块中以单下划线开头的变量或函数被默认当作内部函数或变量,私有的,不会被import * 导入;
#__var 解释器会识别此方式,会被解释器重命名_classname__var,不会轻易被子类覆盖;
#__var__ python定义的特殊成员;




def _terminate_process(process):    #内部成员,import *  默认不会导入,不过可以显示访问
    ''' 判断平台类型已使用对应的kill方式 '''

    if sys.platform == 'win32':
        import ctypes  #提供和C语言兼容的数据类型
        PROCESS_TERMINATE = 1
        handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, process.pid)
        ctypes.windll.kernel32.TerminateProcess(handle, -1)
        ctypes.windll.kernel32.CloseHandle(handle)
    else:
        os.kill(process.pid, signal.SIGTERM)


def _kill_process(process):
    if sys.platform == 'win32':
        _terminate_process(process)
    else:
        os.kill(process.pid, signal.SIGKILL)


def _is_alive(thread):
    if hasattr(thread, "is_alive"):
        return thread.is_alive()
    else:
        return thread.isAlive()


class Command(object):
    '''多线程执行命令,并把返回结果状态报存'''
    def __init__(self, cmd):
        self.cmd = cmd
        self.process = None
        self.out = None
        self.err = None
        self.returncode = None
        self.data = None
        self.exc = None

    def run(self, data, timeout, kill_timeout, env, cwd):
        self.data = data
        environ = dict(os.environ)
        environ.update(env or {})  # 借鉴,也可参数指定默认值

        def target():

            try:
                self.process = subprocess.Popen(self.cmd,
                    universal_newlines=True,
                    shell=False,
                    env=environ,
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    bufsize=0,
                    cwd=cwd,
                )

                if sys.version_info[0] >= 3:
                    self.out, self.err = self.process.communicate(
                        input = bytes(self.data, "UTF-8") if self.data else None   #if 表达式赋值
                    )
                else:
                    self.out, self.err = self.process.communicate(self.data)
            except Exception as exc:
                self.exc = exc


        thread = threading.Thread(target=target)
        thread.start()
#kill timeout
        thread.join(timeout)
        if self.exc:
            raise self.exc
        if _is_alive(thread) :
            _terminate_process(self.process)
            thread.join(kill_timeout)
            if _is_alive(thread):
                _kill_process(self.process)
                thread.join()
        self.returncode = self.process.returncode
        return self.out, self.err


class ConnectedCommand(object):
    def __init__(self,
        process=None,k
        std_in=None,
        std_out=None,
        std_err=None):

        self._process = process
        self.std_in = std_in
        self.std_out = std_out
        self.std_err = std_out
        self._status_code = None

    def __enter__(self):    #实现上下文管理
        return self

    def __exit__(self, type, value, traceback):   
        self.kill()

    @property                                  #装饰器方法实现的属性,内部私有特性禁止外部直接操作,由此设置属性;
    def status_code(self):
        """The status code of the process.
        If the code is None, assume that it's still running.
        """
        return self._status_code

    @property
    def pid(self):
        """The process' PID."""
        return self._process.pid

    def kill(self):
        """Kills the process."""
        return self._process.kill()

    def expect(self, bytes, stream=None):
        """Block until given bytes appear in the stream."""
        if stream is None:
            stream = self.std_out

    def send(self, str, end='\n'):
        """Sends a line to std_in."""
        return self._process.stdin.write(str+end)

    def block(self):
        """Blocks until command finishes. Returns Response instance."""
        self._status_code = self._process.wait()



class Response(object):
    """A command's response"""

    def __init__(self, process=None):
        super(Response, self).__init__()

        self._process = process
        self.command = None
        self.std_err = None
        self.std_out = None
        self.status_code = None
        self.history = []


    def __repr__(self):
        if len(self.command):
            return '<Response [{0}]>'.format(self.command[0])
        else:
            return '<Response>'


def expand_args(command):
    """Parses command strings and returns a Popen-ready list."""

    # Prepare arguments.
    if isinstance(command, (str, unicode)):  #内置函数 判断变量类型
        splitter = shlex.shlex(command.encode('utf-8'))
        splitter.whitespace = '|'
        splitter.whitespace_split = True
        command = []

        while True:
            token = splitter.get_token()
            if token:
                command.append(token)
            else:
                break

        command = list(map(shlex.split, command)) #map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

    return command


def run(command, data=None, timeout=None, kill_timeout=None, env=None, cwd=None):
    """Executes a given commmand and returns Response.
    Blocks until process is complete, or timeout is reached.
    """

    command = expand_args(command)

    history = []
    for c in command:

        if len(history):
            # due to broken pipe problems pass only first 10 KiB
            data = history[-1].std_out[0:10*1024]  #str 分片

        cmd = Command(c)
        try:
            out, err = cmd.run(data, timeout, kill_timeout, env, cwd)
            status_code = cmd.returncode
        except OSError as e:
            out, err = '', u"\n".join([e.strerror, traceback.format_exc()])
            status_code = 127

        r = Response(process=cmd)

        r.command = c
        r.std_out = out
        r.std_err = err
        r.status_code = status_code

        history.append(r)

    r = history.pop()
    r.history = history

    return r


def connect(command, data=None, env=None, cwd=None):
    """Spawns a new process from the given command."""

    # TODO: support piped commands
    command_str = expand_args(command).pop()
    environ = dict(os.environ)
    environ.update(env or {})

    process = subprocess.Popen(command_str,
        universal_newlines=True,
        shell=False,
        env=environ,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        bufsize=0,
        cwd=cwd,
    )

    return ConnectedCommand(process=process)



Pingbacks已打开。

引用地址

评论
  1. Sluts Online Sluts Online 发布于 2020年11月30日 01:30 #

    <a href="https://hdsexycams.com/">adultchatave</a> <a href="https://chickwebcams.com/">adult sex chat</a>

  2. 서울 출장 서울 출장 发布于 2020年11月30日 01:32 #

    Hi! I could have sworn I've been to this web site
    before but after browsing through a few of the articles I realized it's new to me.
    Anyways, I'm certainly pleased I stumbled upon it and I'll be bookmarking it and checking back often!

  3. 서울 출장 서울 출장 发布于 2020年11月30日 01:32 #

    Hi! I could have sworn I've been to this web site before but after browsing through a few of the articles I realized it's new to me.
    Anyways, I'm certainly pleased I stumbled upon it and I'll
    be bookmarking it and checking back often!

  4. search engine search engine 发布于 2020年11月30日 01:35 #

    Hi there, i read your blog from time to time and i own a similar one and i was just wondering if you get a lot of spam feedback?
    If so how do you stop it, any plugin or anything you can advise?
    I get so much lately it's driving me mad so any help is very much
    appreciated.

  5. search engine search engine 发布于 2020年11月30日 01:36 #

    Hi there, i read your blog from time to time and i own a similar one and i was
    just wondering if you get a lot of spam feedback? If so how do you stop
    it, any plugin or anything you can advise? I get
    so much lately it's driving me mad so any help is very much appreciated.

  6. 비트코인홀짝 비트코인홀짝 发布于 2020年11月30日 01:50 #

    Normally I don't learn post on blogs, however I wish to say that this write-up very forced me to check out and do so!
    Your writing style has been amazed me. Thanks, quite great article.

  7. 비트코인홀짝 비트코인홀짝 发布于 2020年11月30日 01:51 #

    Normally I don't learn post on blogs, however I wish to say that this write-up very forced me to check out and
    do so! Your writing style has been amazed me. Thanks, quite
    great article.

  8. PaulGal PaulGal 发布于 2020年11月30日 01:53 #

    <a href="https://viagrapak.com/">viagra cost comparison</a> <a href="https://dexamethasone365.com/">dexamethasone 4 mg tablet</a> <a href="https://oviagra.com/">cheap sildenafil online uk</a> <a href="https://viagra40.com/">sildenafil 20 mg brand name</a> <a href="https://tadalafilpos.com/">cialis for men</a>

  9. allstate claims allstate claims 发布于 2020年11月30日 02:51 #

    <a href="https://bbcarinsurance.com/">amigo insurance</a> <a href="https://carinsurancedns.com/">low cost auto insurance michigan</a>

  10. Crystal Healing Crystal Healing 发布于 2020年11月30日 02:51 #

    I'm truly enjoying the design and layout of
    your site. It's a very easy on tthe eyes which makes it much more pleasant for me to come here and visit more
    often. Did you hire out a designer to create yohr theme?

    Outstanding work!

  11. CarlGal CarlGal 发布于 2020年11月30日 03:02 #

    <a href="https://retinoa.com/">retino cream price</a> <a href="https://pharmacytopp.com/">canadian online pharmacy no prescription</a> <a href="https://cialislm.com/">cialis india purchase</a> <a href="https://cialismn.com/">price for cialis in canada</a> <a href="https://viagrapl.com/">cost for generic sildenafil</a>

  12. tasarim maske tasarim maske 发布于 2020年11月30日 03:52 #

    Undeniably believe that which you said. Your favorite justification appeared to be on the internet the easiest thing to be aware of.
    I say to you, I definitely get annoyed while people consider worries that they just do not know about.
    You managed to hit the nail upon the top and defined out the whole thing without
    having side effect , people could take a signal. Will likely
    be back to get more. Thanks

  13. tasarim maske tasarim maske 发布于 2020年11月30日 03:52 #

    Undeniably believe that which you said. Your favorite justification appeared to be
    on the internet the easiest thing to be aware of.
    I say to you, I definitely get annoyed while people
    consider worries that they just do not know about.
    You managed to hit the nail upon the top and defined out the whole
    thing without having side effect , people could take a signal.
    Will likely be back to get more. Thanks

  14. AmyGal AmyGal 发布于 2020年11月30日 03:53 #

    <a href="https://viagrapak.com/">how to buy viagra in usa</a>

  15. free id test ace333 free id test ace333 发布于 2020年11月30日 04:12 #

    It is appropriate time to make a few plans for
    the long run and it's time to be happy. I've
    read this submit and if I may I desire to counsel
    you some attention-grabbing issues or suggestions.
    Perhaps you could write next articles regarding this article.
    I wish to read even more things approximately it!

  16. free id test ace333 free id test ace333 发布于 2020年11月30日 04:12 #

    It is appropriate time to make a few plans for the long run and
    it's time to be happy. I've read this submit and if I may I desire
    to counsel you some attention-grabbing issues or suggestions.
    Perhaps you could write next articles regarding this article.
    I wish to read even more things approximately it!

  17. T Tops Clothing Pink Mountain T Tops Clothing Pink Mountain 发布于 2020年11月30日 04:19 #

    Attractive section of content. I just stumbled upon your weblog and in accession capital to assert that
    I get actually enjoyed account your blog posts. Any way I will
    be subscribing to your augment and even I achievement you access consistently
    rapidly.

  18. T Tops Clothing Pink Mountain T Tops Clothing Pink Mountain 发布于 2020年11月30日 04:19 #

    Attractive section of content. I just stumbled
    upon your weblog and in accession capital to assert that I get actually enjoyed account your blog posts.
    Any way I will be subscribing to your augment and even I achievement you access consistently rapidly.

  19. LisaGal LisaGal 发布于 2020年11月30日 04:20 #

    <a href="https://tadalafilat.com/">best cialis prices</a>

  20. http://tat.e-nkama.ru http://tat.e-nkama.ru 发布于 2020年11月30日 04:38 #

    This design is steller! You obviously know how to keep a reader amused.
    Between your wit and your videos, I was almost moved to start
    my own blog (well, almost...HaHa!) Excellent job. I really enjoyed what you had to say, and
    more than that, how you presented it. Too cool!

  21. http://tat.e-nkama.ru http://tat.e-nkama.ru 发布于 2020年11月30日 04:39 #

    This design is steller! You obviously know
    how to keep a reader amused. Between your wit and your videos, I was almost moved
    to start my own blog (well, almost...HaHa!) Excellent job.
    I really enjoyed what you had to say, and more than that, how you presented it.
    Too cool!

  22. idn poker deposit idn poker deposit 发布于 2020年11月30日 04:39 #

    Howdy, i read your blog occasionally and i own a similar one and i was just wondering if you get a lot
    of spam remarks? If so how do you protect against it, any plugin or anything you can advise?
    I get so much lately it's driving me crazy so any support is very
    much appreciated.

  23. idn poker deposit idn poker deposit 发布于 2020年11月30日 04:40 #

    Howdy, i read your blog occasionally and i own a similar one and i was just wondering
    if you get a lot of spam remarks? If so how do you protect against it,
    any plugin or anything you can advise? I get so much lately
    it's driving me crazy so any support is very much
    appreciated.

  24. Antoniospous Antoniospous 发布于 2020年11月30日 04:46 #

    https://tadgeneric100.com/ buy tadalafil online
    <a href=" https://tadgeneric100.com/# ">buy cheap tadalafil</a> tadalafil pharmacy
    <a href=https://canadaedgeneric.com/#>online pharmacy</a> buy generic drugs online from india

  25. travel destinations travel destinations 发布于 2020年11月30日 04:57 #

    We are a group of volunteers and opening a new scheme in our community.
    Your web site offered us with valuable info to work on. You've done an impressive job and our whole community will be thankful to you.

  26. travel destinations travel destinations 发布于 2020年11月30日 04:57 #

    We are a group of volunteers and opening a new scheme in our community.
    Your web site offered us with valuable info to work on. You've done an impressive job and our whole community will be
    thankful to you.

  27. VC SEA VC SEA 发布于 2020年11月30日 05:03 #

    Following the day, the individual will have got
    a good sense as to what an enterprise will probably be worth,
    and exactly what they are likely to pay it off.

  28. VC SEA VC SEA 发布于 2020年11月30日 05:03 #

    Following the day, the individual will have got a good sense
    as to what an enterprise will probably be worth,
    and exactly what they are likely to pay it off.

  29. JimGal JimGal 发布于 2020年11月30日 05:10 #

    <a href="https://levaquine.com/">levaquin price</a> <a href="https://internetpharmacysale.com/">legal canadian pharmacy online</a> <a href="https://cialisbz.com/">buy cialis generic online</a>

  30. jacob jacob 发布于 2020年11月30日 05:26 #

    Great article! That is the kind of info that are meant
    to be shared across the web. Shame on Google for not positioning this post upper!
    Come on over and visit my website . Thanks =)

  31. jacob jacob 发布于 2020年11月30日 05:26 #

    Great article! That is the kind of info that are meant to be shared
    across the web. Shame on Google for not positioning this
    post upper! Come on over and visit my website .
    Thanks =)

  32. tree removal south gate ca tree removal south gate ca 发布于 2020年11月30日 05:39 #

    Wonderful beat ! I would like to apprentice
    while you amend your site, how can i subscribe for a blog site?
    The account aided me a acceptable deal. I had been a little
    bit acquainted of this your broadcast provided bright clear idea

  33. tree removal south gate ca tree removal south gate ca 发布于 2020年11月30日 05:39 #

    Wonderful beat ! I would like to apprentice while you amend your site, how
    can i subscribe for a blog site? The account aided me a acceptable
    deal. I had been a little bit acquainted of this your broadcast provided
    bright clear idea

  34. Briandot Briandot 发布于 2020年11月30日 05:43 #

    https://paydayloanstrust1h.com/ payday loans online
    <a href=" https://sildgeneric100.com/# ">sildenafil online</a> sildenafil
    <a href=https://canadaedgeneric.com/#>best place to buy generic drugs</a> buy generic drugs

  35. motivation motivation 发布于 2020年11月30日 05:58 #

    Hey there would you mind letting me know which hosting company you're utilizing?
    I've loaded your blog in 3 completely different
    internet browsers and I must say this blog loads a lot faster then most.
    Can you suggest a good internet hosting provider at a reasonable
    price? Cheers, I appreciate it!

  36. motivation motivation 发布于 2020年11月30日 05:58 #

    Hey there would you mind letting me know which hosting company you're utilizing?
    I've loaded your blog in 3 completely different internet browsers and
    I must say this blog loads a lot faster then most.
    Can you suggest a good internet hosting provider at a reasonable price?
    Cheers, I appreciate it!

  37. KimGal KimGal 发布于 2020年11月30日 06:02 #

    <a href="https://pharmacytopp.com/">legal online pharmacies in the us</a>

  38. thanku thanku 发布于 2020年11月30日 06:06 #

    Do you mibd if I quote a few of your posts as long ass I provide credit andd sources
    back to your site? My blog site is in the exact same area of interest as yours and my viwitors
    would definutely benefit from some of the information youu provide here.
    Pleaqse let me know if this okwy with you. Many thanks!

  39. thanku thanku 发布于 2020年11月30日 06:06 #

    Do you mind if I quote a feww of your posts as long ass
    I provide credit and sources back to your site? My bllog site is in the exact same area of interest aas yours and my visitors would
    definitely benefit from some of the information you provide
    here. Please let me know if thiss okay with you. Many thanks!

  40. EvaGal EvaGal 发布于 2020年11月30日 06:07 #

    <a href="http://viagrapnp.com/">order generic viagra</a>

  41. Payday Payday 发布于 2020年11月30日 06:09 #

    <a href="http://ozcashadvance.com/">ez cash payday loans</a>

  42. kasino online kasino online 发布于 2020年11月30日 06:09 #

    Keep on working, grеat job! http://taoli99.com/comment/html/?174467.html

  43. whatsapp porno imagem whatsapp porno imagem 发布于 2020年11月30日 06:18 #

    I used to be able to find good information from your blog posts.

  44. daftar bandar judi online daftar bandar judi online 发布于 2020年11月30日 06:18 #

    Currently it looks like Expression Engine is the top blogging platform available right now.
    (from what I've read) Is that what you are using on your blog?

  45. whatsapp porno imagem whatsapp porno imagem 发布于 2020年11月30日 06:18 #

    I used to be able to find good information from your
    blog posts.

  46. Pkv Games Pkv Games 发布于 2020年11月30日 06:38 #

    I read this post completely regarding the difference of
    most up-to-date and earlier technologies, it's remarkable article.

  47. Pkv Games Pkv Games 发布于 2020年11月30日 06:38 #

    I read this post completely regarding the difference of most up-to-date and earlier technologies, it's
    remarkable article.

  48. bandar poker idnplay bandar poker idnplay 发布于 2020年11月30日 06:39 #

    It's really a great and helpful piece of info. I'm happy that you shared this helpful info with us.
    Please keep us up to date like this. Thank you for sharing.

  49. bandar poker idnplay bandar poker idnplay 发布于 2020年11月30日 06:39 #

    It's really a great and helpful piece of info. I'm happy
    that you shared this helpful info with us. Please keep us up to date like this.

    Thank you for sharing.

  50. File transfer File transfer 发布于 2020年11月30日 06:41 #

    Very nice article, totally what I needed.

  51. Cullinan 2021 Cullinan 2021 发布于 2020年11月30日 06:48 #

    I wanted to thank you for this great read!! I certainly loved every little bit of it.

    I have you book marked to look at new things you post…

  52. Cullinan 2021 Cullinan 2021 发布于 2020年11月30日 06:48 #

    I wanted to thank you for this great read!! I certainly
    loved every little bit of it. I have you book marked to look at new things you post…

  53. MBBS Study Abroad MBBS Study Abroad 发布于 2020年11月30日 07:11 #

    I simply could not go away your site before suggesting that I
    actually loved the usual information an individual provide to your guests?
    Is going to be again frequently to investigate cross-check new posts

  54. m88cvf m88cvf 发布于 2020年11月30日 07:44 #

    I'm not sure where you're getting your info, but great topic.
    I needs to spend some time learning more or understanding more.
    Thanks for fantastic information I was looking for this info for my mission.

  55. site site 发布于 2020年11月30日 07:57 #

    Juust wish too ssay your article is as astonishing.
    The clearness on your put up is simply nice and i could suppose you're
    a professional in this subject. Well with your permisson allow
    me to seize your RSS feed to stay upp to date with impending
    post. Thank you 1,000,000 and please keep up the
    rewarding work.
    site

  56. site site 发布于 2020年11月30日 07:58 #

    Just wsh to say your article is as astonishing. The clearness on your
    put up is simply nice and i could suppose you're a professional in this subject.
    Well with your permissuon allow me to seize your RSS feed tto
    sty uup too date with impending post. Thank you 1,000,000 and please
    keep up the rewarding work.
    site

  57. vc South east asia vc South east asia 发布于 2020年11月30日 08:10 #

    I do think you could potentially rationally determine using this that any governing administration support of the airlines need
    to entail having many value or zeroing the shareholders or what ever,
    in fairness, although i do not have any distinctive.

  58. vc South east asia vc South east asia 发布于 2020年11月30日 08:10 #

    I do think you could potentially rationally determine using this that any governing
    administration support of the airlines need to entail having many value or zeroing the
    shareholders or what ever, in fairness, although i do not have any distinctive.

  59. helicoptere transfert helicoptere transfert 发布于 2020年11月30日 08:12 #

    Pretty section of content. I just stumbled upon your web site and iin accession capital to
    assert that I get in fact enjoyed account your blog
    posts. Any way I will be subscribing to your feeds and even I achievement you access consistently
    quickly.

  60. helicoptere transfert helicoptere transfert 发布于 2020年11月30日 08:12 #

    Pretty section of content. I just stumbled upon your web site and in accession capital too assert that I get in fact enjjoyed account your blog posts.

    Any way I will be subscribing to yohr feeds and ven I acchievement you achcess consistently quickly.

  61. luxury lifestyle luxury lifestyle 发布于 2020年11月30日 08:14 #

    We absolutely love your blog and find most of your post's to be exactly what I'm looking for.
    can you offer guest writers to write content for yourself?
    I wouldn't mind creating a post or elaborating on most of the subjects
    you write about here. Again, awesome website!

  62. luxury lifestyle luxury lifestyle 发布于 2020年11月30日 08:14 #

    We absolutely love your blog and find most of your post's to
    be exactly what I'm looking for. can you offer guest
    writers to write content for yourself? I wouldn't mind creating a post or elaborating on most of the subjects you write about here.
    Again, awesome website!

  63. Cihanbeyli cam balkon Cihanbeyli cam balkon 发布于 2020年11月30日 08:31 #

    I have been browsing online more than 4 hours today, yet I never found any interesting article like yours.
    It's pretty worth enough for me. In my view, if all web owners
    annd bloggers made good content as you did, the
    nnet will be much more useful than ever before.

  64. Cihanbeyli cam balkon Cihanbeyli cam balkon 发布于 2020年11月30日 08:31 #

    I have been browsing online more than 4 hours today, yet
    I never found any interesting article like yours.
    It's pretty worth enough for me. In my view, if all web owners and bloggers
    mmade good content as you did, the net will be much more useful than ever before.

  65. not getting enough sex at home not getting enough sex at home 发布于 2020年11月30日 08:35 #

    Dеfinitely believe tһat ѡhich you said. Your favorite reason seemed to be on thhe internet tһe simplest thing
    to be aware of. I saʏ to you, Ι definitely get annoyed while people consider worries thаt they pplainly do not
    know about. You managed to һit the nail upon the top as well
    as defined out the whole thing without having side effect
    , people could tɑke a signal. Wilⅼ likey be bɑck to gеt more.
    Thanks

  66. not getting enough sex at home not getting enough sex at home 发布于 2020年11月30日 08:36 #

    Definitely beliеve that which you said. Your faѵorite reason seemed to be on the inhternet the simpⅼest thing to be
    aware of. I say to you, I definitеly gett annoyed while people consider worгies that the plainly do not knoѡ about.
    You managed to hit the nail uon the top as weⅼⅼ aas defined out thhe whole thing without having
    side effect , people could take a sіgnal. Willl
    likeⅼy be back to get more. Thanks

  67. 분당출장안마 분당출장안마 发布于 2020年11月30日 09:00 #

    I’m not that much of a online reader to be
    honest but your blogs really nice, keep it up! I'll
    go ahead and bookmark your website to come back down the road.
    Cheers

  68. thủ tục chứng minh tài chính thủ tục chứng minh tài chính 发布于 2020年11月30日 09:10 #

    I used to be able to find good advice from your articles.

  69. ไม้เทียม ไม้เทียม 发布于 2020年11月30日 09:21 #

    I love looking through a post that will make people think.
    Also, thanks for allowing for me to comment!

发表评论