Ամսական պահոցներ՝ Ապրիլի 2019

Ասք տաս տարեկան լինուքս հեռախօսով հաղորդագրութիւն ուղարկել եւ ստանալու մասին

նախաբան

Շաբաթ իրիկուն էր։ Գնացել էի ISTC մի քանի հատ սպասարկիչ թարմացնելու համար։ Ընկերներս այնտեղ էին, ու պարզւում է, որ հաքաթոն էր։ Թեման՝ Օփըն Գավըրնմընթ։

Ընկերներիս հարցրեցի «ինչո՞վ կարող եմ օգնել»։ ասեցին «արի փորձի Twilio-ի կամ այլ հաղորդագրութիւն ուղարկող/ստացող ծառայութիւն տրամադրող ընկերութեան հետ կպնել»։

դէ լաւ։ ինչքա՞ն բարդ կարող է լինել։ ունեն հաւանաբար մի հատ HTTP API, նայեցի, սիրուն ԱՊԻ-ներ ունէին։

դէ լաւ, գրանցուեցի մէկն ու մէկի մօտ, բայց արի ու տես, որ Հայաստանին ոչ մէկ բանի տեղ չի դնում (յետոյ էլ ասում են թէ մեր մօտ ՏՏ-ն զարգացած ա)։

ստանալ

իհարկէ, ես սիրում եմ ամէն ինչ իմ ձեռքերով անել։ ու ես ունեմ Նոկիա Ն900։ ու ինքը աշխատում ա լինուքսով, աւելի կոնկրետ՝ Մաեմոյով։

Շատ լաւ, մի քիչ research արեցի, ու պարզուեց, որ կարող եմ հաղորդագրութիւնները կարդալ D-Bus-ից օգտուելով։ Ինչ-որ փոքր փայթն ծրագիր էր, սակայն չէր աշխատում։ ու քանի որ հաքաթոն էր, ինձ պէտք էր ուղղակի աշխատեցնել այն շատ արագ, մի քանի րոպէ աչքով դիբագ արեցի ու վերջում ստացայ այս կոդը

#!/usr/bin/env python2.5
import sched, time
import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop
import subprocess
import httplib, urllib

def octify(str):
        '''
        Returns a list of octet bytes representing
        each char of the input str.
        '''

        bytes = map(ord, str)
        bitsconsumed = 0
        referencebit = 7
        octets = []

        while len(bytes):
                byte = bytes.pop(0)
                byte = byte >> bitsconsumed

                try:
                        nextbyte = bytes[0]
                        bitstocopy = (nextbyte & (0xff >> referencebit)) << referencebit
                        octet = (byte | bitstocopy)

                except:
                        octet = (byte | 0x00)

                if bitsconsumed != 7:
                        octets.append(byte | bitstocopy)
                        bitsconsumed += 1
                        referencebit -= 1
                else:
                        bitsconsumed = 0
                        referencebit = 7

        return octets

def semi_octify(str):
        '''
        Expects a string containing two digits.
        Returns an octet -
        first nibble in the octect is the first
        digit and the second nibble represents
        the second digit.
        '''
        try:
                digit_1 = int(str[0])
                digit_2 = int(str[1])
                octet = (digit_2 << 4) | digit_1
        except:
                octet = (1 << 4) | digit_1

        return octet


def deoctify(arr):

        referencebit = 1
        doctect = []
        bnext = 0x00

        for i in arr:

                bcurr = ((i & (0xff >> referencebit)) << referencebit) >> 1
                bcurr = bcurr | bnext

                if referencebit != 7:
                        doctect.append( bcurr )
                        bnext = (i & (0xff << (8 - referencebit)) ) >> 8 - referencebit
                        referencebit += 1
                else:
                        doctect.append( bcurr )
                        bnext = (i & (0xff << (8 - referencebit)) ) >> 8 - referencebit
                        doctect.append( bnext )
                        bnext = 0x00
                        referencebit = 1

        return ''.join([chr(i) for i in doctect])


def createPDUmessage(number, msg):
        '''
        Returns a list of bytes to represent a valid PDU message
        '''
        numlength = len(number)
        if (numlength % 2) == 0:
                rangelength = numlength
        else:
                number = number + 'F'
                rangelength = len(number)

        octifiednumber = [ semi_octify(number[i:i+2]) for i in range(0,rangelength,2) ]
        octifiedmsg = octify(msg)
        HEADER = 1
        FIRSTOCTETOFSMSDELIVERMSG = 10
        ADDR_TYPE = 129 #unknown format
        number_length = len(number)
        msg_length = len(msg)
        pdu_message = [HEADER, FIRSTOCTETOFSMSDELIVERMSG, number_length, ADDR_TYPE]
        pdu_message.extend(octifiednumber)
        pdu_message.append(0)
        pdu_message.append(0)
        pdu_message.append(msg_length)
        pdu_message.extend(octifiedmsg)
        return pdu_message


def sendmessage(number, message):

        bus = dbus.SystemBus()
        smsobject = bus.get_object('com.nokia.phone.SMS', '/com/nokia/phone/SMS/ba212ae1')
        smsiface = dbus.Interface(smsobject, 'com.nokia.csd.SMS.Outgoing')
        arr = dbus.Array(createPDUmessage(number.replace('+', '00'), message))

        msg = dbus.Array([arr])
        smsiface.Send(msg,'')


def callback(pdumsg, msgcenter, somestring, sendernumber):

        msglength = int(pdumsg[18])
        msgarray = pdumsg[19:len(pdumsg)]

        msg = deoctify(msgarray)

        if msg > 0:
               print 'New message received from %s' % sendernumber
               print 'Message length %d' % msglength
               print 'Message: %s' % msg
               params = urllib.urlencode({'answer': msg})
               headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
               conn = httplib.HTTPConnection("sms.myserver.am:80")
               conn.request("POST", "/sms", params, headers)
               conn.close()


def listen():
        DBusGMainLoop(set_as_default=True)
        bus = dbus.SystemBus() #should connect to system bus instead of session because the former is where the incoming signals come from
        bus.add_signal_receiver(callback, path='/com/nokia/phone/SMS', dbus_interface='Phone.SMS', signal_name='IncomingSegment')
        gobject.MainLoop().run()


if __name__ == '__main__':
  import time

  def schedule_task(schedule, fn, *args):
      import sched
      s = sched.scheduler(time.time, time.sleep)
      startTime = time.mktime(time.strptime(schedule, '%b %d %H:%M %Y'))
      s.enterabs(startTime, 0, fn, args)
      s.run()

  import getopt, sys
  try:
    opts, args = getopt.getopt(sys.argv[1:],"hlt:", ["help","listen","time="])

  except getopt.GetoptError, err:
    # print help information and exit:
    print str(err) # will print something like "option -a not recognized"
    usage()
    sys.exit(2)
  listening = False
  timeofday = ''
  for opt, arg in opts:
    if opt in ("-h", "--help"):
      usage()
      sys.exit()
    elif opt in ("-l", "--listen"):
      listening = True
    elif opt in ("-t", "--time"):
      timeofday = arg
    else:
      assert False, "unhandled option"

  listen()

Հետաքրքիր բաները կատարւում են listen() եւ callback() ֆունկցիաների մէջ։ listen()-ը լսում ա SMS-ներին, օգտագործելով D-Bus, ու SMS ստանալուց կանչում է callback() ֆունկցիան, որտեղ փոփոխութիւններ եմ կատարել։

Օգտագործելով urllib եւ httplib աւանդական գրադանները, POST հարցում եմ ուղարկում ոմն sms.myserver.am-ին։

ուղարկել

Հաղորդագրութիւն ուղարկելու համար, ես վստահ էի, որ ինչ-որ մէկը, հաստատ մի ծրագիր գրել է, ապա ման եկայ Մաեմոյի շտեմարանում ու գտայ smssend ծրագիրը։

Շատ լաւ, հեռախօսի վրայ աշխատեցնում եմ

apt-get update # հազարի տարի է update չեմ արել
apt-get install smssend

շաաաատ լաւ, հիմա արդէն, պէտք է աւտոմատ ձեւով սպասարկչից ստանամ թէ որ հեռախօսահամարին ինչ պէտք է ուղարկեմ, եւ վերջ, ապա մի քանի րոպէում գրում եմ polling անող ծրագիր HTTP-ի համար։ ջահելները սրան ասում են ծիպը բզող տեխնոլոգիա։

ահա եւ կոդը։

#!/usr/bin/env python2.5
import subprocess
import httplib, urllib
import simplejson as json
import time


def send_sms(num, text):
    print "sending sms"
    subprocess.Popen(["smssend", "-s", "-n", num, "-m", text])


def loop_fetch():
    conn = httplib.HTTPConnection("sms.myserver.am:80")
    conn.request("GET", "/sms")
    s = conn.getresponse().read()
    if s != 'false':
        j = json.loads(s)
        send_sms(j['number'], j['text'])
    time.sleep(10)
    print "waking up"
    loop_fetch()

def loop():
    loop_fetch()

if __name__ == '__main__':
    print "hello!"
    loop()

վերջաբան

ահա, հիմա բացում եմ երկու հատ տերմինալ, ու երկու ծրագրերն էլ աշխատեցնում եմ։

$ chmod +x sms.py
$ ./sms.py
$ chmod +x poll.py
$ ./poll.py

Գնում եմ տղաների մօտ եւ ուրախանալով ասում «տղանե՜ր, չscalable Twilio եմ սարքել»։

ասանկ բաներ…

Պատասխանել մեյլով

Ասք կրկին բլոգելու մասին

Մի քիչ ուզում եմ խօսել եւ անկեղծանալ։

Արդէն մի տարուց աւել է նորմալ չեմ գրառել։ խառն էի, շատ խառն էի։ Կը ներես եթէ երկար ժամանակ է չեմ գրել այստեղ։ ես չեմ մոռացել քո մասին, սիրելի՛ս։

Պատմեմ մի քիչ, թէ ինչեր եմ արել, ինչեր են եղել։ հա՞։

Նախ, մի քանի տեղ դասաւանդել եմ, վատ չէր, ասեմ աւելին՝ ահագին սովորեցի երբ դաս էի տալիս։ որ կարողանաս շատ լաւ բացատրել ուրիշին, պէտք է նախ շատ լաւ հասկանաս։ արդիւնքում տեսական գիտելիքներս սարսափելի լաւացան։

Մի ֆեյլ փորձ ունեցայ ստարտափ վարելու։ Ինձ թւում էր թէ ֆեյլը ես էի, բայց դէ ես տեխնիկական ղեկավարն էի, արի ու տես, որ բիզնեսը շուռ գնաց։ ես նոյնիսկ ամէն բան անում էի, որ տեխնիկապէս կարողանայի բիզնեսին արագ բրդել առաջ։

Ինչեւէ։ անցած բաներ են ։Ճ եկուր ներկայից ու ապագայից խօսենք։ հա՞

Հիմա կեանքումս երկու գլխաւոր բան է կատարւում։

Առաջին. վերջապէս, հիմնեցի իմ սեփական ստարտ-ափը։ անունը՝ illuria security։ արտադրանքը՝ հաքերների թակարդների աւտոմատացման համակարգ։

Երկրորդ. Ուզում եմ գրառել այստեղ, ու շատ, ու միշտ կիսուեմ հետդ։ գիտեմ, հեռուացել ենք, բայց իրար մասին չենք մոռացել, վստահ եմ։

Մինչ յաջորդ հանդիպում։

Ասանկ բաներ…

Պատասխանել մեյլով