After some thinking (over shots of tequila) on how to create a simple, fun, worthwhile event for entrepreneurs, I stumbled upon the idea of getting people together that have something they’d like to pitch, but then forcing them to pitch someone else’s idea, in hopes the favor would be reciprocated.
I initially thought this would be cool, because this concept could have a few benefits. (1) It could force people to talk to strangers about their idea for the first time, this is a big step to many aspiring entrepreneurs. (2) To the audience, it could seem a lot less like a commercial since your not hearing it from the founder. (3) As the founder, it could be great feedback to hear your pitch from another perspective, not to mention hear a bunch of other pitches in lightening talk fashion. (4) As the Pitcher, there’s not a whole lot of pressure or reason to be embarrassed, since it’s not your idea anyway. (5) With the right setting, it could be a lot of fun.
I say *could* because I have no friggin idea, but there’s only one way to find out. And that’s why PitchSwap.co was born.

So, here’s an attempt to lay out some basic ground rules for the inaugural event on June 14.
I hope that covers most of it. But expect to be surprised. I also plan to take a lot of pictures to document the event. So put on your Sunday best (or not) and get your Tickets here.
Cheers!
- Brad
I’ve used a few services in the past to do site “event tracking” (ie Google Analytics) but most didn’t give me all the data and control I need to easily track what was needed… (mostly user identity stuff). Another big difference is that this is all done server-side, which has it’s pros\cons as well.
Anyway, here’s how I did it using CloudMine’s backend service in ~20 lines of code.
Step1. Add this Action Filter to your MVC application (ie Global.asax.cs)
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UserTrackingAttribute : ActionFilterAttribute
{
public static readonly string appId = "your CloudMine app Id";
public static readonly string appSecret = "your CloudMine app Secret";
class PageRequest
{
public int PageId { get; set; }
public Double Created { get; set; }
public string Url { get; set; }
public string UserName { get; set; }
public string UserIP { get; set; }
public string Controller { get; set; }
public string Action { get; set; }
}
public override void OnResultExecuting(ResultExecutingContext context)
{
PageRequest preq = new PageRequest
{
Url = request.RawUrl,
UserIP = request.UserHostAddress,
UserName = context.HttpContext.User.Identity.Name,
Created = ExtensionMethods.JsonDate(DateTime.Now),
Action = (string)context.RequestContext.RouteData.Values["action"],
Controller = (string)context.RouteData.Values["controller"],
PageId = Convert.ToInt32(context.RouteData.Values["Id"]),
};
using (var client = new WebClient())
{
client.Headers.Add("X-CloudMine-ApiKey", appSecret);
client.Headers.Add("Content-Type", "application/json");
var serializer = new JavaScriptSerializer();
var data = serializer.Serialize(preq);
var payload = "{\"PV_" + DateTime.Now.Ticks + "\":" + data + "}";
var bytes = Encoding.Default.GetBytes(payload);
client.UploadDataAsync(new Uri("https://api.cloudmine.me/v1/app/" + appId + "/text"), "PUT", bytes);
}
}
Then… just add the filter attribute [UserTracking] to any controller action and you’re ready to start logging…in real-time.
The full example project is on my GitHub…so go fork it.
I wanted to play around with the Google WebFonts API for some reason and came up with a somewhat cool little web-based utility called:
Demo here: http://www.w3portals.com/logotype
Source: https://github.com/bradoyler/LogoType
It’s a really quick way to create a “draft” logo.
So after you select your colors and Font, you can simply take a screenshot of the page and copy into your favorite image editor. If I guess enough requests, I may even add some other features and additional fonts.
P.S. I seem to get the best resolution in Firefox.
Happy branding!
AddThis just published their 2011 stats on “sharing” across the web.
(via staff)
Starting some research for an upcoming project that integrates with Sharepoint (sigh). Although I wasn’t to excited to start developing against a bloated beast of an “Enterprise” application like SP 2010…but, I pushed through the tears.
I first started playing around with webparts and found it quite clumsy to build and deploy stuff that was purely for experimenting with the SharePoint API.
That’s when I came across the site: http://get-spscripts.com/ which demonstrates how to do all kinds of crazy scripting for Sharepoint using PowerShell. Finally, a legit reason to work on my PowerShell chops.
Here’s a couple functions I came up with:(for these to work, you have to launch the Sharepoint Mgmt Shell as Administrator… and also change some refs to “http://yourSPserver”)
# below are some SP scripts that do some basic tricks
function GetDocInfo
{
#//this checks existence of a file in a specified SPList
Param ( [parameter(Mandatory=$true)][string]$LibName,
[parameter(Mandatory=$true)][string]$DocName
)
$web = Get-SPWeb http://yourSPserver
$docLibrary = $web.Lists[$LibName]
$folder = $docLibrary.RootFolder
$spFilePath = ("/" + $DocName)
$spFullPath = $folder.Url + $spFilePath
write-host $spFullPath "exists: " $web.GetFile($spFullPath).Exists
}
function GetListFields
{
#// This returns all the Fields of a given SPList
#// Also shows how to loop through a collection with 'ForEach'
Param (
[parameter(Mandatory=$true)][string]$ListName
)
$ctx = Get-SPServiceContext http://yourSPserver
$Scope = New-Object Microsoft.SharePoint.SPServiceContextScope $ctx
$web = Get-SPWeb http://yourSPserver
$splist = $web.Lists[$ListName]
$Column = $splist.Fields
foreach($Field in $Column)
{
Write-Host "Field:" $Field
}
}
function QueryList
{
#//This queries the "Title" field of a given value in a given SPList
Param (
[parameter(Mandatory=$true)][string]$Title,
[parameter(Mandatory=$true)][string]$ListName
)
$web = Get-SPWeb http://yourSPserver
$splist = $web.Lists[$ListName]
$spQuery = New-Object Microsoft.SharePoint.SPQuery
$camlQuery = '$Title'
$spQuery.Query = $camlQuery
$spQuery.RowLimit = 10
$spListItems = $spList.GetItems($spQuery)
foreach ($item in $spListItems)
{
write-host "Name:" $item.Name
write-host "Title:" $item["Title"]
}
}
Hope this was helpful! Cheers.
After attending PSL fishbowl last night, I have a few things I’d like to put on the record. I’m not a verbose guy, so this should be rather pithy.
Last night, after I gave my groups 5 min presentation on the chosen topic, “ways to fix the PSL communication/website issues”, I quickly realized I missed an opportunity to really speak my mind about how to make PSL a stronger organization.
So here ya go…
Purpose
Philly Startups Leaders should embrace their name and be an organization for LEADERS. Why not simply support entrepreneurial leaders that are doing awesome things “for” Philadelphia? Fostering this type of environment is exactly what philly needs and can’t be accomplished with monthly happy hours or tech demos. The goal should really be to convince others to step up and earn your stripes in the community.
Challenges
There will always be fragmentation in this type of group simply because of the nature and personalities of its membership. PSL should just accept this reality and stop worrying about the marketing benefits of a “large” mailing list. Why not just FOCUS on finding the next rising leaders the community can rally behind. Do that effectively, and no one will care about maintaining a mailing list. The lesson here, be careful what you measure.
Execution
First off, a strategy has to be formed to recruit members that are leaders in the community. There needs to be a simple process for new members to apply by giving their relevant accomplishments and also a process for existing members to sponsor leaders that should be accepted as members.
Second, a major factor in organizing a group of people that are willing to work with each other and are also be proud of being a part of the group, is having a common bond. So, maybe the only member requirement should be having a major accomplishment in the community (Launching a company, organizing a group or event that helps Philly startups). Also, each member should be somehow recognized for each of their accomplishments. Recognizing members for their work is a great way to inspire others to make contributions and at the same time build a stronger community.
Lastly, a really cool way to strengthen membership is to convince them all to really “work together” once or twice a year. I could see a PSL summit, where all are invited to a 2 or 3 day event of activities that could focus on addressing local issues and team building. This could be an amazingly effective way to form and strengthen relationships amongst members.
That’s all for now…keep the wheels turning.
I was really surprised that I couldn’t find a plugin or widget that already did this, so I figured I’d make a jQuery plugin to read a public google calendar feed and custom format it so that it can be display on your site and have your own styles applied. Here’s how the gCal reader plugin works.
Here’s a link to the github repo: https://github.com/bradoyler/GoogleCalReader-jquery-plugin
Demo is here: http://w3portals.com/gCalReader/
(function ($) {
//Add gcal element
$(document).ready(function () {
$('body').prepend('Loading...');
});
//Resize image on ready or resize
$.gCalReader = function (options) {
//Default settings
var settings = {
feedUri: 'http://www.google.com/calendar/feeds/en.usa%23holiday%40group.v.calendar.google.com/public/full',
maxresults: 20,
displayCount: 1
};
var feedUri = options.feedUri;
if (feedUri.indexOf("public/full") == -1) {
feedUri = settings.feedUri;
}
var options = $.extend(settings, options);
function _run() {
var calendarService = new google.gdata.calendar.CalendarService('GoogleInc-jsguide-1.0');
// The "public/full" feed is used to retrieve events from the named public calendar with full projection.
var query = new google.gdata.calendar.CalendarEventQuery(feedUri);
query.setOrderBy('starttime');
query.setSortOrder('ascending');
query.setFutureEvents(true);
query.setSingleEvents(true);
query.setMaxResults(options.maxresults);
var callback = function (result) {
var entries = result.feed.getEntries();
$('#gcal').html('');
if (options.displayCount) {
$('#gcal').html(entries.length + ' upcoming events');
}
$('#gcal').append('');
for (var i = 0; i < entries.length; i++) {
var eventEntry = entries[i];
var eventTitle = eventEntry.getTitle().getText();
var startDateTime = null;
var eventDate = null;
var eventWhere = null;
var eventContent = eventEntry.getContent().getText();
var times = eventEntry.getTimes();
if (times.length > 0) {
startDateTime = times[0].getStartTime();
eventDate = startDateTime.getDate();
}
var d_names = new Array("Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat");
var m_names = new Array("Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec");
var a_p = "";
var d = eventDate;
var curr_hour = d.getHours();
if (curr_hour < 12) {
a_p = "am";
}
else {
a_p = "pm";
}
if (curr_hour == 0) {
curr_hour = 12;
}
if (curr_hour > 12) {
curr_hour = curr_hour - 12;
}
var curr_min = d.getMinutes();
curr_min = curr_min + "";
if (curr_min.length == 1) {
curr_min = "0" + curr_min;
}
var time = curr_hour + ':' + curr_min + a_p;
var day = eventDate.getDay();
var month = eventDate.getMonth();
var date = eventDate.getDate();
var dayname = d_names[day];
var monthname = m_names[month];
var location = eventEntry.getLocations();
var eventWhere = location[0].getValueString();
var eventhtml = '' + eventTitle + ' When: ' + dayname + ' ' + monthname + ' ' + date + ', ' + time + Where: ' + eventWhere + eventContent;
$('#eventlist').append(eventhtml);
}
};
// Error handler to be invoked when getEventsFeed() produces an error
var handleError = function (error) {
$('#gcal').html(error); };
// Submit the request using the calendar service object
calendarService.getEventsFeed(query, callback, handleError); }
google.setOnLoadCallback(_run);
})(jQuery);
First, go over to http://ipinfodb.com , see how it works and get yourself an API key by signing up for free. If you’re looking to convert an visitors IP address into a geographic location, then here’s a quick code nugget in C#. Have fun!
string ip = Request.ServerVariables["X-Forwarded-For"]
public class LocationInfo
{
public string Country { get; set; }
public string RegionName { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public float Latitude { get; set; }
public float Longitude { get; set; }
}
public static LocationInfo HostIpToPlaceName(string ip)
{
ObjectCache cache = MemoryCache.Default;
var key = "zzzzzgetyourowncodezzzzzz";
string url = "http://api.ipinfodb.com/v3/ip-city/?key={0}&ip={1}&format=xml";
url = String.Format(url,key, ip);
var location = new LocationInfo();
var result = cache[ip] as XDocument;
try
{
if (result == null)
{
result = XDocument.Load(url);
cache.Add(ip, result,
new CacheItemPolicy() { SlidingExpiration = TimeSpan.FromDays(1) });
}
location = (from x in result.Descendants("Response")
select new LocationInfo
{
City = (string)x.Element("cityName"),
RegionName = (string)x.Element("regionName"),
Country = (string)x.Element("countryName"),
ZipCode = (string)x.Element("zipCode"),
Latitude = (float)x.Element("latitude"),
Longitude = (float)x.Element("longitude")
}).First();
return location;
}
}
One thing to notice is that this caches the result for each unique IP address, so that you don’t have to call this API everytime you need this users location. Cheers!
I recently started using cloud-based hosting (AppHarbor.com) for my latest project (Mealtik.com) and I needed a remote storage solution for the images that would be uploaded by users. I was already familiar with Amazon’s Simple Storage service (AWS S3), but never actually built a .Net app that used this API for uploading images to S3.
So…here are the steps to simply get an image published\uploaded to S3.
1. First go get an account with AWS at http://aws.amazon.com/ and then go get your accessKey and SecretKey from your account.
2. Download the AWS SDK for .Net here: http://aws.amazon.com/sdkfornet/ and include the assembly AWSSDK.dll in your project.
3. Here’s the markup:
<input type=”file” id=”fileUpload” name=”fileUpload” size=”23” />
4. Here’s the C#:
HttpPostedFileBase file = Request.Files[0];
if (file.ContentLength > 0) // accept the file
{
string accessKey = "XXXXXXXXXXX";
string secretKey = "122334XXXXXXXXXX";
AmazonS3 client;
using (client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey, secretKey))
{
PutObjectRequest request = new PutObjectRequest();
request.WithBucketName("mealtik")
.WithCannedACL(S3CannedACL.PublicRead)
.WithKey("meals/test.jpg").InputStream = file.InputStream;
S3Response response = client.PutObject(request);
}
}
A few things to point out:
1. I’m uploading my image (“test.jpg”) to folder (“meals”) which is in a bucket called “mealtik”.
2. I’m setting the image permissions to “public read”.
3. I’m using MVC, but the code should work for webforms as well.
As you can see, it’s pretty simple to do, but for some reason I couldn’t find an example of this anywhere on the interwebs. Hope this helps!
[video]