Skip to content

Instantly share code, notes, and snippets.

@takeshik
Created May 2, 2011 01:47
Show Gist options
  • Select an option

  • Save takeshik/951086 to your computer and use it in GitHub Desktop.

Select an option

Save takeshik/951086 to your computer and use it in GitHub Desktop.
MetaTweet (new) Requests code
private static void Main()
{
var fragments = CreateFragments(Regex.Matches(
@"/$a=1$b==44OG44K544OILyEv44OG44K544OI(/!/obj/activities?query=name:ScreenName value:bob/@Single().Account/-or/$c=3$d=4!twitter/users/show?screen_name=bob/)/!/.xml?encoding=utf-8&format=oneline&b64==44OG44K544OILyEv44OG44K544OI",
@"(/(?:\$[^!@\(\)\-]+)?[!@\(\)\-])(.*?(?=/[\$!@\(\)\-]|$))"
).Cast<Match>().Select(m => new [] { m.Groups[1].Value, m.Groups[2].Value, })).Dump();
}
private static IDictionary<String, String> GetVariableTable(String str)
{
return str[1] == '$'
? str
.Substring(2, str.Length - 3)
.Split('$')
.Select(p => p.Split('='))
.ToDictionary(p => p[0], p => p.Length == 3
? Encoding.UTF8.GetString(Convert.FromBase64String(p[2].Length % 4 == 0
? p[2]
: p[2] + new String('=', 4 - (p[2].Length % 4))
))
: p[1]
)
: new Dictionary<String, String>();
}
private static IEnumerable<Fragment> CreateFragments(IEnumerable<String[]> input)
{
Stack<Tuple<IDictionary<String, String>, LinkedList<Fragment>>> stack
= new Stack<Tuple<IDictionary<String, String>, LinkedList<Fragment>>>();
foreach (String[] data in input)
{
Fragment fragment = null;
switch (data[0].Last())
{
case '(':
stack.Push(Tuple.Create(GetVariableTable(data[0]), new LinkedList<Fragment>()));
break;
case ')':
Tuple<IDictionary<String, String>, LinkedList<Fragment>> tuple = stack.Pop();
fragment = new ScopeFragment(tuple.Item1, tuple.Item2.ToArray());
break;
case '!':
Int32 index = data[1].IndexOf("?");
Dictionary<String, String> arguments = index != -1
? data[1].Substring(index + 1).Split('&').Select(p => p.Split('=')).ToDictionary(p => p[0], p => p.Length == 3
? Encoding.UTF8.GetString(Convert.FromBase64String(p[2].Length % 4 == 0
? p[2]
: p[2] + new String('=', 4 - (p[2].Length % 4))
))
: p[1]
)
: new Dictionary<String, String>();
String flowName = data[1].First() == '/' ? "" : data[1].Substring(0, data[1].IndexOf('/'));
String selector = data[1].Substring(flowName.Length, index != -1 ? index - flowName.Length : Int32.MaxValue);
fragment = new FlowFragment(GetVariableTable(data[0]), flowName, selector, arguments);
break;
case '@':
fragment = new CodeFragment(GetVariableTable(data[0]), data[1]);
break;
case '-':
fragment = new ConjunctionFragment(GetVariableTable(data[0]), data[1]);
break;
default:
break;
}
if (fragment != null)
{
if (stack.Any())
{
stack.Peek().Item2.AddLast(fragment);
}
else
{
yield return fragment;
}
}
}
}
#region Types
public class Request
{
public IEnumerable<Fragment> Fragments
{
get;
private set;
}
public String OriginalString
{
get;
private set;
}
}
public enum FragmentType
{
Unknown = 0,
Flow,
Code,
Scope,
Conjunction,
}
public abstract class Fragment
{
public abstract FragmentType Type
{
get;
}
public IDictionary<String, String> Variables
{
get;
private set;
}
protected Fragment(IDictionary<String, String> variables)
{
this.Variables = variables ?? new Dictionary<String, String>();
}
protected String GetVariablesString()
{
return String.Concat(this.Variables.Select(p => "$" + p.Key + "=" + p.Value));
}
}
public class ScopeFragment
: Fragment
{
public override FragmentType Type
{
get
{
return FragmentType.Scope;
}
}
public IEnumerable<Fragment> Fragments
{
get;
private set;
}
public ScopeFragment(IDictionary<String, String> variables, params Fragment[] fragments)
: base(variables)
{
this.Fragments = fragments;
}
public override String ToString()
{
return "/" + this.GetVariablesString() + "(" + String.Concat(this.Fragments.Select(f => f.ToString())) + "/)";
}
}
public class FlowFragment
: Fragment
{
public override FragmentType Type
{
get
{
return FragmentType.Flow;
}
}
public String FlowName
{
get;
private set;
}
public String Selector
{
get;
private set;
}
public IDictionary<String, String> Arguments
{
get;
private set;
}
public FlowFragment(IDictionary<String, String> variables, String flowName, String selector, IDictionary<String, String> arguments)
: base(variables)
{
this.FlowName = flowName;
this.Selector = selector;
this.Arguments = arguments;
}
public override String ToString()
{
return
"/" + this.GetVariablesString() +
"!" + this.FlowName +
this.Selector +
(this.Arguments.Any() ? "?" + String.Join("&", this.Arguments.Select(p => p.Key + "=" + p.Value)) : "");
}
}
public class CodeFragment
: Fragment
{
public override FragmentType Type
{
get
{
return FragmentType.Code;
}
}
public String Code
{
get;
private set;
}
public CodeFragment(IDictionary<String, String> variables, String code)
: base(variables)
{
this.Code = code;
}
public override String ToString()
{
return "/" + this.GetVariablesString() + "@" + this.Code;
}
}
public class ConjunctionFragment
: Fragment
{
public override FragmentType Type
{
get
{
return FragmentType.Conjunction;
}
}
public String Name
{
get;
private set;
}
public ConjunctionFragment(IDictionary<String, String> variables, String name)
: base(variables)
{
this.Name = name;
}
public override String ToString()
{
return "/" + this.GetVariablesString() + "-" + this.Name;
}
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment