Watch, Follow, &
Connect with Us

Embarcadero Blogs

Latest Posts


Mobile Summer School 6: REST & BaaS

Here are the slides and downloads from my mobile summer school session on REST & BAAS. If you just want the slides they are on Slide Share. I’ll post the video and more details here later. For more information on …

Read more »


posted @ Thu, 24 Jul 2014 18:16:18 +0000 by Jim McKeeth


Recent Delphi Articles on the Embarcadero Developer Network

Here are some of the most recent items that I've posted on the Embarcadero Developer Network. A couple more Technology Partner Spotlight articles on VisonLab and Raize, some Skill Sprint video replays, latest NewsFlash newsletter and info on July special offers.

21 JulCreate advanced computer vision applications with zero lines of program code with VisionLab and RAD Studio XE6
Embarcadero Technology Partner Spotlight
Tim DelChiaroArticle
17 JulCreate and Consume a Custom DataSnap REST API with RAD Studio
Replay from the Developer Skill Sprints Webinar Series - RAD Studio, Delphi and C++Builder
Tim DelChiaroVideo
17 JulDeveloper Direct Code Academy Starts July 18
APAC region free online training sessions on BaaS with RAD Studio
Tim DelChiaroArticle
15 JulCool RAD Offers - End July 31, 2014
Upgrade from any version, free Coding in Delphi ebook, and New User Special
Tim DelChiaroeDM
15 JulDeveloper Direct Summer School First 2 Sessions Available On Demand
Learn to create Android and iOS applications with Delphi Object Pascal and C++
Tim DelChiaroArticle
14 JulFree first issue of Blaise Pascal Magazine en español
Technical information on programming with Delphi and Object Pascal
Tim DelChiaroArticle
8 JulEmbarcadero RAD NewsFlash July 2014
Multi-Device Developer News
Tim DelChiaroNewsletter
4 JulIncorporate document processing into your applications with RAD Studio and Gnostice XtremeDocumentStudio
Embarcadero Technology Partner Spotlight
Tim DelChiaroArticle
1 JulSetting up your Devices for iOS Push Notification application development
This video shows you how to set up your iOS devices to be ready for application development of iOS push notifications
Tim DelChiaroVideo
30 JunCreate unique user experiences with RAD Studio XE6 and Raize Components
Embarcadero Technology Partner Spotlight
Tim DelChiaroArticle

posted @ Thu, 24 Jul 2014 08:00:00 +0000 by Tim Del Chiaro


Send Password Reset Emails by adding a new BaaS method with Parse

Recently, I covered the steps necessary to add password reset email notification functionality to your BaaS enabled Delphi XE6 app using Kinvey. Today, I thought I would explain how to do this with Parse.

This demo shows you how to to derive from the existing ParseAPI class (TExtendParseApi = class(TParseApi)) for the Parse component and add a new method for executing Parse’s password reset.

Inside your Parse.com account, you can define email settings for the password reset email.

My application consists of 4 edit controls parented to 4 TListBox items:

  • EditUsername
  • EditPassword
  • EditSessionToken
  • EditEmail

TListBox has GroupingKind set to Grouped and StyleLookUp set to ‘transparentlistboxstyle’.

I added the ParseProvider1 component to my form and entered the AppID, MasterKey and RESTAPIKey that is displayed inside my Parse.com. In order to extend the functionality, I had to add a new method for triggering a password reset email notification which you can see in the code samples below.

Shown: Mobile app running on Windows with Mobile Preview style.

Here is the code for my ExtendParseApiUnit

unit ExtendParseApiUnit;

interface

uses REST.Backend.Parseapi, System.JSON, REST.Client, REST.Types;

type
  TExtendParseApi = class(TParseApi)
  private
  public
    procedure SignupUser(const AUserName, APassword, AEmail: string;
      out ALogin: TParseAPI.TLogin); overload;
    procedure PasswordReset(const AEmail: string);
  end;

implementation

// New version of signup user that has a password parameter
procedure TExtendParseApi.SignupUser(const AUserName, APassword, AEmail: string;
  out ALogin: TParseAPI.TLogin);
var
  LJSON: TJSONObject;
begin
  LJSON := TJSONObject.Create;
  try
    LJSON.AddPair('email', AEmail);
    inherited SignupUser(AUserName, APassword, LJSON, ALogin);
  finally
    LJSON.Free;
  end;
end;

//curl -X POST \
//  -H "X-Parse-Application-Id: cIj01OkQeJ8LUzFZjMnFyJQD6qx0OehYep0mMdak" \
//  -H "X-Parse-REST-API-Key: yVVIeShrcZrdr3e4hMLodfnvLckWBZfTonCYlBsq" \
//  -H "Content-Type: application/json" \
//  -d '{"email":"coolguy@iloveapps.com"}' \
//  https://api.parse.com/1/requestPasswordReset
procedure TExtendParseApi.PasswordReset(const AEmail: string);
var
  LJSON: TJSONObject;
begin
  Request.ResetToDefaults;
  AddAuthParameters;
  Request.Method := TRESTRequestMethod.rmPOST;
  Request.Resource := 'requestPasswordReset';
  LJSON := TJSONObject.Create;
  try
    LJSON.AddPair('email', AEmail);
    Request.AddBody(LJSON);
    Request.Execute;
    CheckForResponseError([201]);
  finally
    LJSON.Free;
  end;
end;

end.

Here is the code for my mobile client

unit ParseFormUnit;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, IPPeerClient,
  REST.OpenSSL, REST.Backend.ParseProvider, FMX.StdCtrls,
  FMX.Edit, ExtendParseApiUnit, FMX.ListBox, FMX.Layouts;

type
  TParseForm = class(TForm)
    ButtonSignup: TButton;
    ButtonPasswordReset: TButton;
    ListBox1: TListBox;
    UserLabel: TListBoxItem;
    EditUserName: TEdit;
    PasswordLabel: TListBoxItem;
    EditPassword: TEdit;
    EmailLabel: TListBoxItem;
    EditEmail: TEdit;
    SessionLabel: TListBoxItem;
    EditSessionToken: TEdit;
    ToolBar1: TToolBar;
    Label5: TLabel;
    ParseProvider1: TParseProvider;
    procedure ButtonSignupClick(Sender: TObject);
    procedure ButtonPasswordResetClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);

  private
    { Private declarations }
    FApi: TExtendParseAPI;
    procedure ClearFields;
  public
    { Public declarations }
  end;

var
  ParseForm: TParseForm;

implementation

{$R *.fmx}

uses REST.Backend.ParseApi, System.JSON;

procedure TParseForm.ButtonPasswordResetClick(Sender: TObject);
begin
  FApi.PasswordReset(EditEmail.Text);
  ShowMessage('Message sent to ' + EditEmail.Text);
end;

procedure TParseForm.ButtonSignupClick(Sender: TObject);
var
  LLogin: TParseAPI.TLogin;
begin
  FApi.SignupUser(EditUsername.Text, EditPassword.Text, EditEmail.Text, LLogin);
  FApi.Login(LLogin);  // Make subsequent calls as this user
  EditSessionToken.Text := LLogin.SessionToken;
  ShowMessage('Welcome ' + LLogin.User.UserName);
end;

procedure TParseForm.FormCreate(Sender: TObject);
begin
  FApi := TExtendParseAPI.Create(Self);
  // Assign appkey, etc.
  ParseProvider1.UpdateApi(FApi);
end;

procedure TParseForm.ClearFields;
begin
  EditUserName.Text := '';
  EditPassword.Text := '';
  EditEmail.Text := '';
  EditSessionToken.Text := '';
end;
end.

Below you see a screenshot of the email that I received after clicking on the ‘Reset Password via Email’ button inside my app:

After clicking on the automatically generated reset URL, you see a web based form where you can reset your password:


posted @ Wed, 23 Jul 2014 21:11:32 +0000 by sarinadupont


Adding a new BaaS method for executing a password reset email notification using Kinvey

A couple of days ago, I covered how to add password reset functionality to your application for resetting the password inside your app.
A common question I got was how to leverage the cloud based password reset email functionality that many BaaS providers offer. Today, I thought I would cover how to add password reset functionality via an email notification to your BaaS enabled mobile application using RAD Studio XE6. This tutorial uses Kinvey, but I am going to do a blog post on Parse soon as well.

This demo shows you how to to derive from the existing Kinvey API class (TExtendKinveyAPI = class(TKinveyAPI)) for the Kinvey component and add a new method for executing Kinvey’s password reset.

Inside your Kinvey.com account, go to AddOns->Messaging->Email Templates and customize your ‘Password Reset‘ email template. There you can define Sender and Reply To information, the Subject line and the HTML for the body of your email. The App Name referenced in the email is the name of your application you defined inside your Kinvey.com account.

My application consists of 4 edit controls parented to 4 TListBox items:

  • EditUsername
  • EditPassword
  • EditSessionToken
  • EditEmail

TListBox has GroupingKind set to Grouped and StyleLookUp set to ‘transparentlistboxstyle’.

I added the KinveyProvider1 component to my form and entered the AppKey, AppSecret and MasterSecret that is displayed inside my Kinvey.com account under ‘AppName’->Manage Environments. In order to extend the functionality, I had to add a new method for triggering a password reset email notification which you can see in the code samples below.


Shown: Mobile app running on Windows with Mobile Preview style.

Here is the code for my ExtendKinveyApiUnit

unit ExtendKinveyApiUnit;

interface

uses REST.Backend.Kinveyapi, System.JSON, REST.Client, REST.Types;

type
  TExtendKinveyApi = class(TKinveyApi)
  private
  public
    procedure SignupUser(const AUserName, APassword, AEmail: string;
      out ALogin: TKinveyApi.TLogin); overload;
    procedure PasswordReset(const AEmail: string);
  end;

implementation

// New version of signup user that has a password parameter
procedure TExtendKinveyApi.SignupUser(const AUserName, APassword, AEmail: string;
  out ALogin: TKinveyApi.TLogin);
var
  LJSON: TJSONObject;
begin
  LJSON := TJSONObject.Create;
  try
    LJSON.AddPair('email', AEmail);
    inherited SignupUser(AUserName, APassword, LJSON, ALogin);
  finally
    LJSON.Free;
  end;
end;

//POST /rpc/:appKey/:email/user-password-reset-initiate HTTP/1.1
//Host: baas.kinvey.com
//Authorization: [Basic Auth with app credentials]
procedure TExtendKinveyApi.PasswordReset(const AEmail: string);
var
  LConnectionInfo: TConnectionInfo;
begin
  Request.ResetToDefaults;
  // Basic Auth
  LConnectionInfo := Self.ConnectionInfo;
  LConnectionInfo.UserName := AEmail;
  ConnectionInfo := LConnectionInfo;
  AddAuthParameter(TAuthentication.UserName);
  // App credentials
  AddAuthParameter(TAuthentication.AppSecret);
  Request.Method := TRESTRequestMethod.rmPOST;
  Request.Resource := 'rpc/{appkey}/{email}/user-password-reset-initiate';
  Request.AddParameter( 'email', AEmail, TRESTRequestParameterKind.pkURLSEGMENT );
  Request.Execute;
  CheckForResponseError([201]);
end;

end.

Here is the code for my mobile client

unit KinveyFormUnit;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, IPPeerClient,
  REST.OpenSSL, REST.Backend.KinveyProvider, FMX.StdCtrls,
  FMX.Edit, ExtendKinveyApiUnit, REST.Backend.ParseProvider, FMX.ListBox,
  FMX.Layouts, REST.Backend.ServiceTypes, REST.Backend.MetaTypes, System.JSON,
  REST.Backend.KinveyServices, REST.Backend.Providers,
  REST.Backend.ServiceComponents;

type
  TKinveyForm = class(TForm)
    EditUserName: TEdit;
    EditPassword: TEdit;
    ButtonSignup: TButton;
    EditEmail: TEdit;
    ButtonPasswordReset: TButton;
    EditSessionToken: TEdit;
    ToolBar1: TToolBar;
    Label5: TLabel;
    ListBox1: TListBox;
    UserLabel: TListBoxItem;
    PasswordLabel: TListBoxItem;
    EmailLabel: TListBoxItem;
    SessionLabel: TListBoxItem;
    KinveyProvider1: TKinveyProvider;
    procedure ButtonSignupClick(Sender: TObject);
    procedure ButtonPasswordResetClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);

  private
    { Private declarations }
    FApi: TExtendKinveyAPI;
    procedure ClearFields;
  public
    { Public declarations }
  end;

var
  KinveyForm: TKinveyForm;

implementation

{$R *.fmx}

uses REST.Backend.KinveyApi;

procedure TKinveyForm.ButtonPasswordResetClick(Sender: TObject);
begin
  FApi.PasswordReset(EditEmail.Text);
  ShowMessage('Message sent to ' + EditEmail.Text);
end;

procedure TKinveyForm.ButtonSignupClick(Sender: TObject);
var
  LLogin: TKinveyAPI.TLogin;
begin
  FApi.SignupUser(EditUsername.Text, EditPassword.Text, EditEmail.Text, LLogin);
  FApi.Login(LLogin);  // Make subsequent calls as this user

  EditSessionToken.Text := LLogin.AuthToken;
  ShowMessage('Welcome ' + LLogin.User.UserName);
end;

procedure TKinveyForm.FormCreate(Sender: TObject);
begin
  FApi := TExtendKinveyAPI.Create(Self);
  KinveyProvider1.UpdateApi(FApi);
end;

procedure TKinveyForm.ClearFields;
begin
  EditUserName.Text := '';
  EditPassword.Text := '';
  EditEmail.Text := '';
  EditSessionToken.Text := '';

end;

end.

Below you see a screenshot of the email that I received after clicking on the ‘Reset Password via Email’ button inside my app:

After clicking on the automatically generated reset URL, you see a web based form where you can reset your password:


posted @ Wed, 23 Jul 2014 16:51:09 +0000 by sarinadupont


Mobile Summer School Lesson 5: App Tethering Round-Up

I substituted for David I. yesterday for Developer Direct Mobile Summer School on Lesson 5: Connecting Mobile and Desktop together using App Tethering. The Summer School landing page and David’s blog maintain a list of downloads for all the previous …

Read more »


posted @ Tue, 22 Jul 2014 10:57:11 +0000 by Jim McKeeth


RAD Studio, C++Builder and Delphi July 2014 Special Offers

If you don't have RAD Studio, Delphi or C++Builder XE6 yet, you won't want to miss out on these offers.

If you are currently on version XE or earlier, July is your best time to upgrade to XE6 because you can upgrade from any earlier version and save up to 45% off the regular new user price.

Don't miss out!
Invent Your Future Today!
Cool Embarcadero RAD offers are soon to end, so hurry and get RAD Studio XE6 now - the most complete multi-device tool for Windows, mobile, wearables and beyond. These special offers for upgrades and new users are available through July 31, 2014.
Get free upgrades and support through the end of 2014
When you buy select RAD Studio, Delphi or C++Builder XE6 New User editions by July 31, 2014 and get FREE support and maintenance including all major upgrades free until the end of 2014.

Upgrade to RAD Studio XE6, Delphi XE6 or C++Builder XE6 from any earlier version
Get the tools you need for modernizing your Windows applications and mobile development for Android and iOS, and save up to 45% off the regular new user license price. Offer available until July 31, 2014.

Buy or upgrade NOW from any version and claim your free Bonus Pack of additional tools including the Coding in Delphi ebook by Nick Hodges, Mida Converter, and VCL and FireMonkey Style Packs to help improve your development skills, simplify your multi-device development and create beautifully styled apps.





posted @ Mon, 21 Jul 2014 10:56:00 +0000 by Tim Del Chiaro


BaaS User Accounts and Password Management

Over the last couple of months, I have been covering various BaaS (Backend-as-a-Service) features introduced in RAD Studio XE6.
Today, I thought I would expand on the User Account Creation and Authentication topic I previously covered by showing you how to allow the user to change their password within your BaaS enabled application.

In this app, I am using Kinvey as my BaaS Provider but the UI and code are the same if you are using Parse.
The app consists of 3 Edit controls: One for Username, one for Password and one for the Session ID.
There are also 4 TButtons on the form: One for Sign Up, one for Login, one for Logout, and one for Change Password.
I parented the input controls to TListbox items and added ListBoxItemGroupHeaders to divide up the UI.

Screenshot: iOS UI at design time; Windows app at runtime with Mobile Preview style

Below is the Object Pascal code for my application:

unit Unit7;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, IPPeerClient,
  REST.OpenSSL, REST.Backend.ServiceTypes, REST.Backend.MetaTypes, System.JSON,
  REST.Backend.KinveyServices, FMX.Edit, FMX.StdCtrls, REST.Backend.Providers,
  REST.Backend.ServiceComponents, REST.Backend.KinveyProvider, FMX.ListBox,
  FMX.Layouts;

type
  TForm7 = class(TForm)
    KinveyProvider1: TKinveyProvider;
    BackendUsers1: TBackendUsers;
    ButtonChangePassword: TButton;
    ButtonLogin: TButton;
    ButtonLogout: TButton;
    ButtonSignup: TButton;
    EditPassword: TEdit;
    EditSessionID: TEdit;
    EditUserName: TEdit;
    ListBox1: TListBox;
    ListBoxItem1: TListBoxItem;
    ListBoxItem2: TListBoxItem;
    ListBoxItem3: TListBoxItem;
    ListBoxGroupHeader1: TListBoxGroupHeader;
    ListBoxGroupHeader2: TListBoxGroupHeader;
    ToolBar1: TToolBar;
    Label1: TLabel;
    procedure ButtonSignupClick(Sender: TObject);
    procedure ButtonLoginClick(Sender: TObject);
    procedure ButtonLogoutClick(Sender: TObject);
    procedure ButtonChangePasswordClick(Sender: TObject);
  private
    { Private declarations }
    FLogin: TBackendEntityValue;
    procedure Login;
    procedure Signup;
  public
    { Public declarations }
  end;

var
  Form7: TForm7;

implementation

{$R *.fmx}

procedure TForm7.ButtonChangePasswordClick(Sender: TObject);
var
  LPassword: TJSONObject;
  LUpdatedAt: TBackendEntityValue;
begin
  LPassword := TJSONObject.Create;
  try
    LPassword.AddPair('password', EditPassword.Text);
    BackendUsers1.Users.UpdateUser(FLogin, LPassword, LUpdatedAt);
    Login;
  finally
    LPassword.Free;
  end;
end;

procedure TForm7.ButtonLoginClick(Sender: TObject);
begin
  Login;
end;

procedure TForm7.ButtonLogoutClick(Sender: TObject);
begin
  BackendUsers1.Users.Logout;
  EditSessionID.Text := '';
  EditUsername.Text := '';
  EditPassword.Text := '';
end;

procedure TForm7.Signup;
begin
  BackendUsers1.Users.SignupUser(EditUserName.Text, EditPassword.Text, nil, FLogin);
  BackendUsers1.Users.Login(FLogin);
  EditSessionID.Text := FLogin.AuthToken;
end;

procedure TForm7.Login;
begin
  BackendUsers1.Users.LoginUser(EditUserName.Text, EditPassword.Text, FLogin);
  BackendUsers1.Users.Login(FLogin);
  EditSessionID.Text := FLogin.AuthToken;
end;

procedure TForm7.ButtonSignupClick(Sender: TObject);
begin
  Signup;
end;

end.

posted @ Fri, 18 Jul 2014 16:38:46 +0000 by sarinadupont


Developer Direct 2014 Mobile School: Lesson 4 Slides and Replays

Wednesday, July 16, 2014: Lesson 4 - Building Powerful Multi-tier, Multi-device Applications using DataSnap REST/JSON

This lesson will show you how to create multi-tier applications (in some cases with zero lines of code) that work with your mobile applications. In this lesson, you will learn how to create middle-tier server applications containing business logic and access to remote enterprise SQL databases. This lesson will also show you how to use the same MastSQL.GDB database in the middle-tier for access and updating, update client information from the mobile app, update customer orders, etc. in the mobile client that serves data to iOS and Android devices.

Lesson 4 Slides

You can download the slides (PPTX and PDF) slides and a PDF draft of an unreleased, "Tutorial: Using a REST DataSnap Server with an Application and FireDAC" for the Lesson 4 (Wednesday, July 16, 2014) Developer Direct 2014 Mobile School at

http://cc.embarcadero.com/item/29906

Download size is 4.3mb.

This will allow you to follow along during the course lessons for both C++ and Object Pascal.

Lesson 4 Replays

Watch the Lesson 4 replay videos on YouTube at

Mobile School Lessons Registration

Registration and course information for all six lessons can be found at

http://forms.embarcadero.com/RADSummerSchool2014

Developer Direct Mobile School YouTube Playlist

You will find all of the Developer Direct Mobile School lesson replays (usually appearing within 24 hours of the actual lesson) using the following YouTube playlist:

https://www.youtube.com/playlist?list=PLwUPJvR9mZHhLj-gegxc0KpGE0wL2zVBo


posted @ Wed, 16 Jul 2014 00:56:24 +0000 by David Intersimone


June 2014 BOGO Promo Redemption Info

I have heard some reports that some people are confused or don't understand what the June Buy One Get One offer was or how to redeem it. It's really pretty simple. The offer was a free second tool of equal or lesser value with purchase of qualifying RAD Studio, Delphi and C++Builder XE6 products. Here are some steps to help you redeem if you purchased during the offer period.

Step 1 - Check if you are eligible. If you purchased a Delphi, C++Builder or RAD Studio XE6 product between May 26, 2014 and June 30, 2014 then check the list of qualifying products at http://www.embarcadero.com/bogo-terms to see if the product you purchased qualifies to get a free additional tool. You will see that some products like Starter, Academic, Recharge and Multi-Packs didn't qualify.

Step 2 - Install and register your XE6 product. The free product is issued to the same named user as the paid product so you have to register your paid product first.

Step 3 - Choose your free product from the redemption page. Click here for the redemption page. Enter your registered XE6 serial number and choose your free products.

You'll get your free product serial number emailed to the email address on the account where your XE6 tool is registered and you'll get a download link for the software.

We're giving some extra days after the July 15 deadline to redeem. Be sure you do it within the next week.

Here are some potential issues and how to avoid them:

  • If it won't let you redeem because you haven't installed and registered your XE6 product yet, install and register your XE6 product and then come back to the page to redeem
  • Don't choose a C++Builder or RAD Studio Add-On Pack as your free item if you own Delphi. Don't choose a "Professional edition Add-On Pack" if you don't have a Professional edition tool to add it to. Just be sure to choose an additional tool that logically makes sense.
  • If it won't let you redeem because you logged into the redemption page with a different user account than you used to register the product, then make sure you log into the redemption page with the same account that you used to register your XE6 product.
  • If it says your purchase was made outside the offer period then check to see if you did purchase outside the date range and if that is the case, you are unfortunately not eligible for this offer.

If your purchase didn't qualify for this offer, you are still likely eligible to download the free Bonus Pack items including the FireMonkey and VCL Premium Style Packs from http://cc.embarcadero.com/reg/rad_studio.


posted @ Tue, 15 Jul 2014 10:03:00 +0000 by Tim Del Chiaro


Developer Direct 2014 Mobile School: Lesson 3 Slides and Replays

Monday, July 14, 2014: Lesson 3 - Accessing Local Storage and Data

In this lesson, we explore local storage covering a range of options including using INI files and local document storage. This lesson will also show how to use FireDAC database access components to connect to and use local SQLite, InterBase IBLite and IBToGo. You will understand the core concepts when writing and reading from disk on iOS and Android.

Lesson 3 Slides

You can download the slides (PPTX and PDF) slides for the Lesson 3 (Monday, July 14, 2014) Developer Direct 2014 Mobile School at

http://cc.embarcadero.com/item/29905

Download size is 6.2mb.

This will allow you to follow along during the course lessons for both C++ and Object Pascal.

Lesson 3 Replays

Watch the Lesson 3 replay videos on YouTube at

Mobile School Lessons Registration

Registration and course information for all six lessons can be found at

http://forms.embarcadero.com/RADSummerSchool2014

Developer Direct Mobile School YouTube Playlist

You will find all of the Developer Direct Mobile School lesson replays (usually appearing within 24 hours of the actual lesson) using the following YouTube playlist:

https://www.youtube.com/playlist?list=PLwUPJvR9mZHhLj-gegxc0KpGE0wL2zVBo


posted @ Mon, 14 Jul 2014 14:52:00 +0000 by David Intersimone


Server Response from: BLOGS1