Tumgik
#file under : explore with tz
lgcdowoon · 1 year
Text
Tumblr media
EXPLORE WITH TZ : x-hunting in qilou solo COUNT : 581 words
since he was alone and figured footage of him just walking won’t do much good, he spoke his thoughts aloud as he walked down qilou old street with the camera man next to him. “so daeho-hyung and i’s letter is x--which is easy to remember because it’s just a cross, like this” he made a large x with his arms. “now what starts with x...this is hard, i can only think of an x-ray.” he decided that rather than trying to figured out every word that started with x, he would just keep on the move and hope he came across something with an x on it. he and the staff assigned to him walked around the street for a bit, chatting and trying to find an x of some sort--dowoon was getting desperate.
“ooh this is an x!” seeing something in the distance, he ran straight towards the item, leaving the cameraman in the dust. once the camera man caught up with dowoon, he presented the item with glee and pride. it was a sign that read, xylophones 50% off in english, at the front of a small music store. he then started messing with the sign, noticing the tight screws on it. “it’s kinda on there tight--so do i take a picture, or i guess i could ask if i could borrow the sign for a bit? the owner might not mind.” he peered into the store to get a read on who was attending the store. that was when the manager next to the cameraman started to giggle. “what--i need the x right? we’re supposed to find the x... and dowoon look confused. the manager then re-explained the rules, he had to buy the item for one and “OOOOH find an item with a name that starts with x...i see.” he scratched the back of his head, laughing but feeling ashamed for the mistake. 
“well, i guess i’ll keep looking...” he took all of about five steps away from the store, before he remembered the sign itself. “OH! we can get a xylophone!” once again he laughed but had a look of shame on his face as he opened the door into the shop. “this is why the hyungs don’t usually leave me alone” he joked towards the camera.
he decided to take a moment to look around the shop. when he still had the time, he would spend much of a day practicing piano, so he went straight to that small section and played a bit. he played mary had a little lamb for the camera, as well as the part of type zero’s song, before the dawn that he could remember (which wasn’t a lot), “i’m out of practice--i hope my old piano teacher isn’t watching...sorry choi-seonsaengnim.” ashamed seemed to be the emotino of the day for him. he continued to browse around the shop. it wasn’t anything crazy elaborate or large, a couple pianos, guitars, and drums on display--probably family owned if he had to guess. 
he got to the percussion section and went straight towards the xylephones. “jackpot!!!” he exclaimed. there was a box marked sale and filled with loose damaged or lost xylephone keys. he figured that had to count right?? he got as many as he could get--plus a xun, because he thought it seemed cool. with that, he thanked the shop owner and realize he had to race back to the meeting spot to tally the result--he really hoped he won.
3 notes · View notes
mbaljeetsingh · 7 years
Text
Hello, Laravel? Communicating with PHP through Phone Calls!
Twilio is a SaaS application which enables developers to build telephone applications using web technologies. In this two-part series, we will leverage Twilio to build a weather forecast app that is accessed using the telephone system. The backend will be written with the Laravel framework (an exploratory video course is available for purchase here, or in the form of written tutorials here).
In this part, we will create a simple program that will allow a user to call a phone number that we buy from Twilio, enter a zipcode, and receive the current weather forecast. The user can also get the weather for any day of the week via the voice menu prompts. In the second part of this series, we will leverage what was built in this article to allow the user to interact with the app via SMS (text message).
Prerequisites
Development Environment
This article assumes Homestead Improved is installed. It is not necessary to use it, but the commands might differ slightly if you use a different environment. If you are not familiar with Homestead and want to produce similar results as this article aims to produce, please visit this SitePoint article that shows how to set up Homestead, and if you need a crash course in Vagrant, please see this post. Additionally, if this whets your appetite and you feel like exploring PHP development environments in depth, we have a book about that available for purchase.
Dependencies
We will create a new Laravel project and then add the Twilio PHP SDK and Guzzle HTTP client library to the project:
cd ~/Code composer create-project --prefer-dist laravel/laravel Laravel 5.4.* cd Laravel composer require "twilio/sdk:^5.7" composer require "guzzlehttp/guzzle:~6.0"
Development
Let's go through all the steps, one by one.
Routes
Open up the routes/web.php file and add the following ones:
Route::group(['prefix' => 'voice', 'middleware' => 'twilio'], function () { Route::post('enterZipcode', 'VoiceController@showEnterZipcode')->name('enter-zip'); Route::post('zipcodeWeather', 'VoiceController@showZipcodeWeather')->name('zip-weather'); Route::post('dayWeather', 'VoiceController@showDayWeather')->name('day-weather'); Route::post('credits', 'VoiceController@showCredits')->name('credits'); });
In this app, all requests will be under the /voice path. When Twilio first connects to the app, it will go to /voice/enterZipcode via HTTP POST. Depending on what happens in the telephone call, Twilio will make requests to other endpoints. This includes /voice/zipcodeWeather for providing today's forecast, /voice/dayWeather, for providing a particular day's forecast, and /voice/credits for providing information on where the data came from.
Service Layer
We are going to add a service class. This class will hold a lot of the business logic that will be shared between the voice telephone app and the SMS app.
Create a new sub-folder called Services inside the app folder. Then, create a file called WeatherService.php and put the following content into it:
<?php namespace App\Services; use Illuminate\Support\Facades\Cache; use Twilio\Twiml; class WeatherService { }
This is a large file in the project, so we will build it piece by piece. Put the following pieces of code in this section inside our new service class:
public $daysOfWeek = [ 'Today', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ];
We will use this array to map a day of the week to a number; Sunday = 1, Monday = 2, etc.
public function getWeather($zip, $dayName) { $point = $this->getPoint($zip); $tz = $this->getTimeZone($point); $forecast = $this->retrieveNwsData($zip); $ts = $this->getTimestamp($dayName, $zip); $tzObj = new \DateTimeZone($tz->timezoneId); $tsObj = new \DateTime(null, $tzObj); $tsObj->setTimestamp($ts); foreach ($forecast->properties->periods as $k => $period) { $startTs = strtotime($period->startTime); $endTs = strtotime($period->endTime); if ($ts > $startTs and $ts < $endTs) { $day = $period; break; } } $response = new Twiml(); $weather = $day->name; $weather .= ' the ' . $tsObj->format('jS') . ': '; $weather .= $day->detailedForecast; $gather = $response->gather( [ 'numDigits' => 1, 'action' => route('day-weather', [], false) ] ); $menuText = ' '; $menuText .= "Press 1 for Sunday, 2 for Monday, 3 for Tuesday, "; $menuText .= "4 for Wednesday, 5 for Thursday, 6 for Friday, "; $menuText .= "7 for Saturday. Press 8 for the credits. "; $menuText .= "Press 9 to enter in a new zipcode. "; $menuText .= "Press 0 to hang up."; $gather->say($weather . $menuText); return $response; }
The getWeather method takes a zipcode with the day of the week and crafts the text of a weather forecast. First, it figures out the reference time for the day requested, and then looks up the weather forecast by doing a foreach over the array of forecast data. After that, it returns a Voice TwiML response. Below is a sample of what is returned:
<?xml version="1.0" encoding="UTF-8"?> <Response> <Gather numDigits="1" action="/voice/dayWeather"> <Say> This Afternoon the 31st: Sunny, with a high near 72. South southwest wind around 8 mph. Press 1 for Sunday, 2 for Monday, 3 for Tuesday, 4 for Wednesday, 5 for Thursday, 6 for Friday, 7 for Saturday. Press 8 for the credits. Press 9 to enter in a new zipcode. Press 0 to hang up. </Say> </Gather> </Response>
The <Gather> tag tells Twilio to expect input from the user's keypad. The numDigits attribute says how many digits to expect. The action attribute says what endpoint to contact next.
protected function retrieveNwsData($zip) { return Cache::remember('weather:' . $zip, 60, function () use ($zip) { $point = $this->getPoint($zip); $point = $point->lat . ',' . $point->lng; $url = 'http://ift.tt/2siEbBl' . $point . '/forecast'; $client = new \GuzzleHttp\Client(); $response = $client->request('GET', $url, [ 'headers' => [ 'Accept' => 'application/geo+json', ] ]); return json_decode((string)$response->getBody()); }); }
The retrieveNwsData method gets the weather forecast data. First, the method checks to see if a copy of the zipcode's weather forecast is in cache. If not, then the Guzzle HTTP client is used to make an HTTP GET request to the National Weather Service's (NWS) API endpoint http://ift.tt/2siJ4Kk. To get the geographic point of the zipcode, a call is made to the getPoint method before doing the request to the weather API. The response from the API endpoint is the weather forecast in GeoJSON format. The forecast is for every day and night for a week (with some exceptions we will discuss later); 14 entries in all. We cache the API response for an hour because making the request is slow, plus we do not want to hit the government servers too frequently and get banned.
protected function getPoint($zip) { return Cache::remember('latLng:' . $zip, 1440, function () use ($zip) { $client = new \GuzzleHttp\Client(); $url = 'http://ift.tt/1p5neFv'; $response = $client->request('GET', $url, [ 'query' => [ 'postalcode' => $zip, 'countryBias' => 'US', 'username' => env('GEONAMES_USERNAME') ] ]); $json = json_decode((string)$response->getBody()); return $json->postalCodes[0]; }); }
The getPoint method maps a zipcode to a geographic point. This is done by using the GeoNames API. The results are cached for a day because using the API is slow.
protected function getTimeZone($point) { $key = 'timezone:' . $point->lat . ',' . $point->lng; return Cache::remember($key, 1440, function () use ($point) { $client = new \GuzzleHttp\Client(); $url = 'http://ift.tt/1C9XM7m'; $response = $client->request('GET', $url, [ 'query' => [ 'lat' => $point->lat, 'lng' => $point->lng, 'username' => env('GEONAMES_USERNAME') ] ]); return json_decode((string) $response->getBody()); }); }
The getTimeZone method is used to get the timezone that a geographic point resides inside. The GeoNames API is also used and the results are cached for a day for the same reasons.
Continue reading %Hello, Laravel? Communicating with PHP through Phone Calls!%
via SitePoint http://ift.tt/2siIbSa
0 notes
t-baba · 7 years
Photo
Tumblr media
Hello, Laravel? Communicating with PHP through Phone Calls!
Twilio is a SaaS application which enables developers to build telephone applications using web technologies. In this two-part series, we will leverage Twilio to build a weather forecast app that is accessed using the telephone system. The backend will be written with the Laravel framework (an exploratory video course is available for purchase here, or in the form of written tutorials here).
In this part, we will create a simple program that will allow a user to call a phone number that we buy from Twilio, enter a zipcode, and receive the current weather forecast. The user can also get the weather for any day of the week via the voice menu prompts. In the second part of this series, we will leverage what was built in this article to allow the user to interact with the app via SMS (text message).
Prerequisites
Development Environment
This article assumes Homestead Improved is installed. It is not necessary to use it, but the commands might differ slightly if you use a different environment. If you are not familiar with Homestead and want to produce similar results as this article aims to produce, please visit this SitePoint article that shows how to set up Homestead, and if you need a crash course in Vagrant, please see this post. Additionally, if this whets your appetite and you feel like exploring PHP development environments in depth, we have a book about that available for purchase.
Dependencies
We will create a new Laravel project and then add the Twilio PHP SDK and Guzzle HTTP client library to the project:
cd ~/Code composer create-project --prefer-dist laravel/laravel Laravel 5.4.* cd Laravel composer require "twilio/sdk:^5.7" composer require "guzzlehttp/guzzle:~6.0"
Development
Let's go through all the steps, one by one.
Routes
Open up the routes/web.php file and add the following ones:
Route::group(['prefix' => 'voice', 'middleware' => 'twilio'], function () { Route::post('enterZipcode', 'VoiceController@showEnterZipcode')->name('enter-zip'); Route::post('zipcodeWeather', 'VoiceController@showZipcodeWeather')->name('zip-weather'); Route::post('dayWeather', 'VoiceController@showDayWeather')->name('day-weather'); Route::post('credits', 'VoiceController@showCredits')->name('credits'); });
In this app, all requests will be under the /voice path. When Twilio first connects to the app, it will go to /voice/enterZipcode via HTTP POST. Depending on what happens in the telephone call, Twilio will make requests to other endpoints. This includes /voice/zipcodeWeather for providing today's forecast, /voice/dayWeather, for providing a particular day's forecast, and /voice/credits for providing information on where the data came from.
Service Layer
We are going to add a service class. This class will hold a lot of the business logic that will be shared between the voice telephone app and the SMS app.
Create a new sub-folder called Services inside the app folder. Then, create a file called WeatherService.php and put the following content into it:
<?php namespace App\Services; use Illuminate\Support\Facades\Cache; use Twilio\Twiml; class WeatherService { }
This is a large file in the project, so we will build it piece by piece. Put the following pieces of code in this section inside our new service class:
public $daysOfWeek = [ 'Today', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ];
We will use this array to map a day of the week to a number; Sunday = 1, Monday = 2, etc.
public function getWeather($zip, $dayName) { $point = $this->getPoint($zip); $tz = $this->getTimeZone($point); $forecast = $this->retrieveNwsData($zip); $ts = $this->getTimestamp($dayName, $zip); $tzObj = new \DateTimeZone($tz->timezoneId); $tsObj = new \DateTime(null, $tzObj); $tsObj->setTimestamp($ts); foreach ($forecast->properties->periods as $k => $period) { $startTs = strtotime($period->startTime); $endTs = strtotime($period->endTime); if ($ts > $startTs and $ts < $endTs) { $day = $period; break; } } $response = new Twiml(); $weather = $day->name; $weather .= ' the ' . $tsObj->format('jS') . ': '; $weather .= $day->detailedForecast; $gather = $response->gather( [ 'numDigits' => 1, 'action' => route('day-weather', [], false) ] ); $menuText = ' '; $menuText .= "Press 1 for Sunday, 2 for Monday, 3 for Tuesday, "; $menuText .= "4 for Wednesday, 5 for Thursday, 6 for Friday, "; $menuText .= "7 for Saturday. Press 8 for the credits. "; $menuText .= "Press 9 to enter in a new zipcode. "; $menuText .= "Press 0 to hang up."; $gather->say($weather . $menuText); return $response; }
The getWeather method takes a zipcode with the day of the week and crafts the text of a weather forecast. First, it figures out the reference time for the day requested, and then looks up the weather forecast by doing a foreach over the array of forecast data. After that, it returns a Voice TwiML response. Below is a sample of what is returned:
<?xml version="1.0" encoding="UTF-8"?> <Response> <Gather numDigits="1" action="/voice/dayWeather"> <Say> This Afternoon the 31st: Sunny, with a high near 72. South southwest wind around 8 mph. Press 1 for Sunday, 2 for Monday, 3 for Tuesday, 4 for Wednesday, 5 for Thursday, 6 for Friday, 7 for Saturday. Press 8 for the credits. Press 9 to enter in a new zipcode. Press 0 to hang up. </Say> </Gather> </Response>
The <Gather> tag tells Twilio to expect input from the user's keypad. The numDigits attribute says how many digits to expect. The action attribute says what endpoint to contact next.
protected function retrieveNwsData($zip) { return Cache::remember('weather:' . $zip, 60, function () use ($zip) { $point = $this->getPoint($zip); $point = $point->lat . ',' . $point->lng; $url = 'http://ift.tt/2siEbBl' . $point . '/forecast'; $client = new \GuzzleHttp\Client(); $response = $client->request('GET', $url, [ 'headers' => [ 'Accept' => 'application/geo+json', ] ]); return json_decode((string)$response->getBody()); }); }
The retrieveNwsData method gets the weather forecast data. First, the method checks to see if a copy of the zipcode's weather forecast is in cache. If not, then the Guzzle HTTP client is used to make an HTTP GET request to the National Weather Service's (NWS) API endpoint http://ift.tt/2siJ4Kk. To get the geographic point of the zipcode, a call is made to the getPoint method before doing the request to the weather API. The response from the API endpoint is the weather forecast in GeoJSON format. The forecast is for every day and night for a week (with some exceptions we will discuss later); 14 entries in all. We cache the API response for an hour because making the request is slow, plus we do not want to hit the government servers too frequently and get banned.
protected function getPoint($zip) { return Cache::remember('latLng:' . $zip, 1440, function () use ($zip) { $client = new \GuzzleHttp\Client(); $url = 'http://ift.tt/1p5neFv'; $response = $client->request('GET', $url, [ 'query' => [ 'postalcode' => $zip, 'countryBias' => 'US', 'username' => env('GEONAMES_USERNAME') ] ]); $json = json_decode((string)$response->getBody()); return $json->postalCodes[0]; }); }
The getPoint method maps a zipcode to a geographic point. This is done by using the GeoNames API. The results are cached for a day because using the API is slow.
protected function getTimeZone($point) { $key = 'timezone:' . $point->lat . ',' . $point->lng; return Cache::remember($key, 1440, function () use ($point) { $client = new \GuzzleHttp\Client(); $url = 'http://ift.tt/1C9XM7m'; $response = $client->request('GET', $url, [ 'query' => [ 'lat' => $point->lat, 'lng' => $point->lng, 'username' => env('GEONAMES_USERNAME') ] ]); return json_decode((string) $response->getBody()); }); }
The getTimeZone method is used to get the timezone that a geographic point resides inside. The GeoNames API is also used and the results are cached for a day for the same reasons.
Continue reading %Hello, Laravel? Communicating with PHP through Phone Calls!%
by Christopher Thomas via SitePoint http://ift.tt/2rwsNPa
0 notes
matthewjosephtaylor · 7 years
Text
VSCode Is Awesome, Is Microsoft Giving Up On Being Evil?
I'm typing this in VS Code.
A year or so ago I started using Atom as my light, friendly, small-footprint, general-purpose editor (for those times when using a heavy IDE like IntelliJ or Eclipse is too large a tool for the job).
I've enjoyed my time with Atom. Like any useful tool there are some things I don't like.
Written in coffeescript (A worthy language in its time but it lost, and I personally was never a fan)
Doesn't handle large files well (neither does VS Code but it has the saving grace of refusing to open large files vs lagging-to-death or crashing, which is much preferred behavior)
There are probably others but those are the ones I can think of off the top of my head, and really it is a pretty solid editor, and I wasn't actively looking for a replacement.
Then comes an interesting new fact into my life, thanks to a lunch-discussion with a co-worker.
I learned that the source code for VS Code is under the MIT license
I knew that VS Code was licensed under an 'open source' license but there are OS licenses and there are OS licenses. I had assumed that Microsoft being Microsoft that they would have chosen an OS license that would would have allowed access to the source code but would have denied forking (you can see but you can't touch). So I wrote it off as not being worth my time and attention.
I'm extremely picky on what I invest my time on. Rule of thumb: not 100% open = you have to pay me $$$ to spend time/attention on it. Closed source (including look but no touch licenses) is generally too big a risk unless there is a very large, obvious, and immediate payback.
The MIT license is well-known as perhaps the simplest, most permissive 'do what you will with the code' license available. So this new information got my attention.
Life would be simpler if evil companies would just continue to do evil things. But alas, the world it seems is not that simple.
I've been playing around with VS Code for over the weekend, and so far it is doing everything that I have asked of it.
Key bindings are simple to remap (but perhaps a tad incomplete (no 'go back to last edit' that I've been able to find so far)).
Every plugin I've wanted I've found, and they have been high-quality with recent development. The plugin 'marketplace' is an active repository with a good rating system, and easy access to source repositories.
The 'project explorer' is easily put away and recalled.
TypeScript is a language I'm actually excited to use. Long have I envied Lisp/Emacs user's ability to easily reshape their editor at will. I had thought Atom would be the editor to scratch that itch, but I think I was just too turned off by coffeescript to make a go of it. Hopefully this will be the one...
The built in terminal is amazingly good. Like open vim in it and and it behaves well good. I can see myself living in this terminal.
Haha I just figured out that it appears to be using Apple Terminal under the hood. Well played.
Tasks are powerful but weakened significantly by being project-based. Hopefully this feature request will make it through.
In the meantime the macros plugin looks kind of cool, and it might just be a that a 'better tasks' plugin already exists or might become my first plugin :)
VS Code Gotchas
There is no spell checker 'built in'. No worries, there are plugins, but one of the top plugins is not to be trusted (sends all text to a 3rd party). There is now a warning message at the top of this plugin, but the fact that it exists at all, and got so popular is worrying
Complaints
The name 'Visual Studio Code'
Too similar a name to 'Visual Studio' and 'Code' too generic so it messes up google searches (I'm currently using 'vscode' which seems to work fairly well)
The 'Visual Studio' branding is not helpful for adoption among those of us who wrote off all things Microsoft long ago which I'm sure is hindering adoption (and I very much want the tools I use to be widely adopted to get as many network effect benefits as possible).
Everything requires a restart .
Reboots are not acceptable, there is no reason why things can't be reloaded on the fly except poor programming practices.
WTF is this '.vscode' crap.
It is NOT COOL to litter up the filesystem with editor meta-data, especially without asking and making it clear this is going to happen.
Unintuitive that there are 'user settings' which I'm guessing are the global settings and 'workspace settings' which are tied to a project folder and seem to be responsible for creating the '.vscode' folder. It creates a '.vscode' merely by 'looking at' the 'workspace settings' even if no changes are made.
Themes
There needs to be a theme explorer
Should be easier/possible for me to tweak theme properties
Still a little bit evil:
Telemetry/crash reporting on by default
How to turn it off
Has Microsoft really turned the corner?
I fully admit that I had written Microsoft off many years ago. The OS was crap. The company engaged in ethically unsound practices that garnered them a well-deserved reputation as an 'evil' company. There was simply nothing about the company's actions, or philosophy that lead me to believe they were worth any brain-cells, and so I intentionally stopped paying attention to them and avoided everything they produced.
I will stand by this decision to shun that despicable organization, and I think it has served me well over the years.
But recent actions such as releasing VS Code, TypesScript and I was amazed to learn in my lunch-time conversation dotNet including the CLR Under an MIT License, including a patent promise (which is better than nothing, but is still questionable...but really the whole idea software patents is questionable, so I'm going to leave that aside for the moment), strongly suggests that Microsoft is becoming worthy of attention once again. They are even making baby-steps into turning Windows into a decent OS by adopting compatibility with Linux of all things.
Actions do speak.
While I will forever remain wary. I am, for now, no longer going to auto-ignore everything coming out of Microsoft. They have earned a cautious, untrusting, eye...but an eye all the same. :)
0 notes
lgcdowoon · 1 year
Text
snapshoot.
EXPLORE WITH TZ : haikou volcanic cluster mission ft. @lgcdaeho
“that hike was intense.” dowoon groaned as he found his bearings and they settled in the rainforest. he didn’t expect how physical this show was going to be. he wished he had done some gym time before they left. “so now we have to take photos of different flowers right? how long do we have?” he asked for confirmation. “10 minutes? that shouldn’t be too hard should it hyung.” he figured they had a leg up since there were two of them and only one of parker. 
taking out the camera they were allowed to use, he started looking around. “oh hyung!!”dowoon cheered, “there is a super pretty flower right next to you--pose and i’ll get a cute photo” he gave daeho a moment to pose and then snapped the photo. looking at the picture, he compliment daeho, “nice! you look really pretty” and then showed the photo to the other. “now what else is around here...” he looked around, trying to find some pretty flowers to snap pictures of.
3 notes · View notes