sawtooth 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +38 -0
- data/Rakefile +12 -0
- data/lib/sawtooth.rb +8 -0
- data/lib/sawtooth/builder.rb +106 -0
- data/lib/sawtooth/document.rb +158 -0
- data/lib/sawtooth/parser.rb +67 -0
- data/lib/sawtooth/rules.rb +6 -0
- data/lib/sawtooth/rules/base.rb +32 -0
- data/lib/sawtooth/rules/call_rule.rb +60 -0
- data/lib/sawtooth/rules/delegate_rule.rb +75 -0
- data/lib/sawtooth/rules/set.rb +64 -0
- data/lib/sawtooth/rules/text_rule.rb +55 -0
- data/lib/sawtooth/version.rb +3 -0
- data/sawtooth.gemspec +25 -0
- data/test/files/delegate.xml +34 -0
- data/test/files/statuses.xml +422 -0
- data/test/sawtooth/builder_test.rb +102 -0
- data/test/sawtooth/document_test.rb +119 -0
- data/test/sawtooth/parser_test.rb +17 -0
- data/test/sawtooth/readme_test.rb +21 -0
- data/test/sawtooth/rules/delegate_rule_test.rb +44 -0
- data/test/sawtooth/rules/text_rule_test.rb +59 -0
- data/test/sawtooth/rules_set_test.rb +49 -0
- data/test/test_helper.rb +25 -0
- metadata +161 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'sawtooth/rules/base'
|
2
|
+
|
3
|
+
module Sawtooth
|
4
|
+
module Rules
|
5
|
+
|
6
|
+
# The call rule allows to execute custom blocks
|
7
|
+
# of code upon start or finish.
|
8
|
+
#
|
9
|
+
# CallRule.new do
|
10
|
+
# on_start { |doc, name, attrs| doc << name }
|
11
|
+
# on_finish { |doc, name, text| doc.pop }
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
class CallRule < Base
|
15
|
+
|
16
|
+
# Should be initialized with a block, the
|
17
|
+
# block invokes the current instance.
|
18
|
+
def initialize(options = {}, &block)
|
19
|
+
@options = options || {}
|
20
|
+
self.instance_eval(&block) if block_given?
|
21
|
+
end
|
22
|
+
|
23
|
+
# Configure the `on_start` block.
|
24
|
+
def on_start(&block)
|
25
|
+
@options[:start] = block
|
26
|
+
end
|
27
|
+
|
28
|
+
# Configure the `on_finish` block.
|
29
|
+
def on_finish(&block)
|
30
|
+
@options[:finish] = block
|
31
|
+
end
|
32
|
+
|
33
|
+
# Called when the beginning of a matching XML node is encountered.
|
34
|
+
#
|
35
|
+
# - doc, the current sawtooth document stack
|
36
|
+
# - node, the current node
|
37
|
+
def start(path, doc, node)
|
38
|
+
invoke_block @options[:start], doc, node
|
39
|
+
end
|
40
|
+
|
41
|
+
# Called when the end of a matching XML node is encountered.
|
42
|
+
# If an element has no body, this method is called with an empty
|
43
|
+
# string instead.
|
44
|
+
#
|
45
|
+
# - doc, the current sawtooth document stack
|
46
|
+
# - node, the current node
|
47
|
+
def finish(path, doc, node)
|
48
|
+
invoke_block @options[:finish], doc, node
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
def invoke_block(block, doc, node)
|
53
|
+
case block.arity
|
54
|
+
when 1; block.call(doc)
|
55
|
+
else block.call(doc, node)
|
56
|
+
end if block && block.respond_to?(:call)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'sawtooth/rules/base'
|
2
|
+
require 'sawtooth/rules/call_rule'
|
3
|
+
|
4
|
+
module Sawtooth
|
5
|
+
module Rules
|
6
|
+
|
7
|
+
# Can delegate to another set of rules, can be used
|
8
|
+
# to map the same rules to multiple tags.
|
9
|
+
#
|
10
|
+
# Delegates must be mapped using `path/**`
|
11
|
+
class DelegateRule < Base
|
12
|
+
|
13
|
+
class CallbacksRule < Base
|
14
|
+
|
15
|
+
attr_reader :delegate
|
16
|
+
|
17
|
+
def initialize(delegate); @delegate = delegate end
|
18
|
+
def start(path, doc, node)
|
19
|
+
rule = @delegate.rules && @delegate.rules.find('@document:before')
|
20
|
+
rule.start(path, doc, node) if rule && rule.respond_to?(:start)
|
21
|
+
end
|
22
|
+
|
23
|
+
def finish(path, doc, node)
|
24
|
+
rule = @delegate.rules && @delegate.rules.find('@document:after')
|
25
|
+
rule.finish(path, doc, node) if rule && rule.respond_to?(:finish)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Access the set of rules and prefix.
|
30
|
+
attr_accessor :rules, :prefix, :path
|
31
|
+
|
32
|
+
# Initialize with a set of rules and a prefix
|
33
|
+
def initialize(options = {}, &block)
|
34
|
+
self.path = options[:path]
|
35
|
+
self.rules = options[:rules]
|
36
|
+
self.prefix = options[:prefix] || ''
|
37
|
+
end
|
38
|
+
|
39
|
+
# Builds a special rule which invokes :before and :after callbacks on the
|
40
|
+
# supplied set of rules.
|
41
|
+
def before_after_callbacks_rule
|
42
|
+
@before_after_callbacks_rule ||= CallbacksRule.new(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
def start(path, doc, node)
|
46
|
+
new_path = relative_path(path)
|
47
|
+
rule = rules && rules.find(new_path)
|
48
|
+
rule.start(new_path, doc, node) if rule && rule.respond_to?(:start)
|
49
|
+
end
|
50
|
+
|
51
|
+
def finish(path, doc, node)
|
52
|
+
new_path = relative_path(path)
|
53
|
+
rule = rules && rules.find(new_path)
|
54
|
+
rule.finish(new_path, doc, node) if rule && rule.respond_to?(:finish)
|
55
|
+
end
|
56
|
+
|
57
|
+
def print_rule
|
58
|
+
"#{self.class.name}, rules=[\n\t".tap do |str|
|
59
|
+
str << rules.print_rules.split("\n").join("\n\t") << "\n" if rules && rules.respond_to?(:print_rules)
|
60
|
+
str << "]"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
# Returns the relative current path, based
|
67
|
+
# on the prefix.
|
68
|
+
def relative_path(path)
|
69
|
+
path[self.prefix.size..-1].gsub(%r{^/}, '').tap do |pth|
|
70
|
+
#puts "self.prefix=#{self.prefix}, path=#{path}, result=#{pth}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Sawtooth
|
2
|
+
module Rules
|
3
|
+
|
4
|
+
# An entry in the `Set`.
|
5
|
+
class RuleEntry
|
6
|
+
|
7
|
+
# Both path and the rule are accessible.
|
8
|
+
attr_accessor :path, :rule
|
9
|
+
attr_reader :orig_path
|
10
|
+
|
11
|
+
# Creates a new entry using path and the rule instance.
|
12
|
+
def initialize(path, rule)
|
13
|
+
self.path, self.rule = path, rule
|
14
|
+
end
|
15
|
+
|
16
|
+
def path=(path)
|
17
|
+
@orig_path = path
|
18
|
+
case path
|
19
|
+
when Regexp; @path = path
|
20
|
+
else @path = %r{\A#{path.gsub('**', '.+').gsub('*', '[^/]+')}\z}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns `true` if the current path matches.
|
25
|
+
def matches?(test)
|
26
|
+
test =~ path
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Provides a set of routes and all the matching and globbing.
|
31
|
+
#
|
32
|
+
# Rules are matched using `File.fnmatch`.
|
33
|
+
class Set
|
34
|
+
|
35
|
+
# Accessor for the array of rules.
|
36
|
+
attr_reader :items
|
37
|
+
|
38
|
+
# Creates a new rule set.
|
39
|
+
def initialize
|
40
|
+
@items = []
|
41
|
+
end
|
42
|
+
|
43
|
+
# Adds a new `RuleEntry`.
|
44
|
+
def add(path, rule)
|
45
|
+
self.items << RuleEntry.new(path, rule)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Find a rule matching the supplied path (or path array), if not
|
49
|
+
# an array, then it must be separated by `/`.
|
50
|
+
#
|
51
|
+
# If no matching rule is found, `default` is returned.
|
52
|
+
def find(*path)
|
53
|
+
path = path.flatten.join('/')
|
54
|
+
match = self.items.find { |rule| rule.matches?(path) }
|
55
|
+
match.rule if match
|
56
|
+
end
|
57
|
+
|
58
|
+
# Pretty print rules.
|
59
|
+
def print_rules
|
60
|
+
items.inject('') { |str, entry| str << "#{entry.orig_path} => #{entry.rule.print_rule}\n" }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'sawtooth/rules/base'
|
2
|
+
|
3
|
+
module Sawtooth
|
4
|
+
module Rules
|
5
|
+
|
6
|
+
# Sets a value on an object on the stack based on
|
7
|
+
# the text contents of a tag.
|
8
|
+
#
|
9
|
+
# Inputs can further be converted by supplying a custom block
|
10
|
+
# which converts the input, this is useful to perform e.g. parsing
|
11
|
+
# dates or similar.
|
12
|
+
#
|
13
|
+
class TextRule < Base
|
14
|
+
|
15
|
+
# Default Text Converter
|
16
|
+
CONVERTER = Proc.new { |input| input = input.strip; input.length > 0 ? input : nil }
|
17
|
+
|
18
|
+
# Settings
|
19
|
+
attr_reader :name, :converter
|
20
|
+
|
21
|
+
def initialize(name = nil, &block)
|
22
|
+
@name = name
|
23
|
+
@converter = block_given? ? block : CONVERTER
|
24
|
+
end
|
25
|
+
|
26
|
+
# If theres some text, send it to reciever (top object).
|
27
|
+
def finish(path, doc, node)
|
28
|
+
value = converter.call(node.text)
|
29
|
+
attr_name = (self.name.respond_to?(:call) ? self.name.call(node.name) : self.name) || underscore(node.name)
|
30
|
+
obj = doc.top
|
31
|
+
|
32
|
+
case
|
33
|
+
when obj.respond_to?("#{attr_name}="); obj.send("#{attr_name}=", value)
|
34
|
+
when obj.respond_to?(:key?); obj[attr_name] = value
|
35
|
+
when obj.respond_to?(:push); obj.push value
|
36
|
+
# else, warning...?
|
37
|
+
end if value
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
# Underscore a value, tries to fallback to AS if
|
43
|
+
# available.
|
44
|
+
def underscore(str)
|
45
|
+
return str.underscore if str.respond_to?(:underscore)
|
46
|
+
|
47
|
+
str.to_s.gsub(/::/, '/').
|
48
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
49
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
50
|
+
tr("-", "_").
|
51
|
+
downcase
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/sawtooth.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/sawtooth/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "sawtooth"
|
6
|
+
s.version = Sawtooth::VERSION
|
7
|
+
s.authors = ["Lukas Westermann"]
|
8
|
+
s.email = ["lukas.westermann@gmail.com"]
|
9
|
+
s.homepage = ""
|
10
|
+
s.summary = %q{Declarative XML parsing using nokogiri}
|
11
|
+
s.description = %q{Provides an interface on top of nokogiri to parse XML files like Apache Digester.}
|
12
|
+
|
13
|
+
s.rubyforge_project = "sawtooth"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_runtime_dependency "nokogiri"
|
21
|
+
|
22
|
+
s.add_development_dependency "rake", ">= 0.9.2"
|
23
|
+
s.add_development_dependency "appraisal", ">= 0.4.0"
|
24
|
+
s.add_development_dependency "minitest", ">= 2.10.0"
|
25
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<Articles>
|
3
|
+
<Author>lukas</Author>
|
4
|
+
<Version>35</Version>
|
5
|
+
|
6
|
+
<Section>
|
7
|
+
<Name>Ruby</Name>
|
8
|
+
<Article>
|
9
|
+
<Blocks id="first">
|
10
|
+
<Title>Didum</Title>
|
11
|
+
<Text>Dadam</Text>
|
12
|
+
</Blocks>
|
13
|
+
</Article>
|
14
|
+
<Article>
|
15
|
+
<Blocks id="second">
|
16
|
+
<Title>Argh</Title>
|
17
|
+
<Text>Urgh</Text>
|
18
|
+
</Blocks>
|
19
|
+
</Article>
|
20
|
+
</Section>
|
21
|
+
<MainArticle>
|
22
|
+
<Blocks id="main">
|
23
|
+
<Title>Foobar</Title>
|
24
|
+
<Text>Barfoo</Text>
|
25
|
+
</Blocks>
|
26
|
+
</MainArticle>
|
27
|
+
|
28
|
+
<MainArticle>
|
29
|
+
<Blocks id="other">
|
30
|
+
<Title>Other</Title>
|
31
|
+
<Text>Article</Text>
|
32
|
+
</Blocks>
|
33
|
+
</MainArticle>
|
34
|
+
</Articles>
|
@@ -0,0 +1,422 @@
|
|
1
|
+
<statuses type="array">
|
2
|
+
<status>
|
3
|
+
<created_at>Sat Aug 09 05:38:12 +0000 2008</created_at>
|
4
|
+
<id>882281424</id>
|
5
|
+
<text>I so just thought the guy lighting the Olympic torch was falling when he began to run on the wall. Wow that would have been catastrophic.</text>
|
6
|
+
<source>web</source>
|
7
|
+
<truncated>false</truncated>
|
8
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
9
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
10
|
+
<favorited></favorited>
|
11
|
+
<user>
|
12
|
+
<id>4243</id>
|
13
|
+
<name>John Nunemaker</name>
|
14
|
+
<screen_name>jnunemaker</screen_name>
|
15
|
+
<location>Mishawaka, IN, US</location>
|
16
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
17
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
18
|
+
<url>http://addictedtonew.com</url>
|
19
|
+
<protected>false</protected>
|
20
|
+
<followers_count>486</followers_count>
|
21
|
+
</user>
|
22
|
+
</status>
|
23
|
+
<status>
|
24
|
+
<created_at>Sat Aug 09 02:04:56 +0000 2008</created_at>
|
25
|
+
<id>882145663</id>
|
26
|
+
<text>@ijonas - wow that stuff sounds sweet</text>
|
27
|
+
<source>web</source>
|
28
|
+
<truncated>false</truncated>
|
29
|
+
<in_reply_to_status_id>882005142</in_reply_to_status_id>
|
30
|
+
<in_reply_to_user_id>1000471</in_reply_to_user_id>
|
31
|
+
<favorited></favorited>
|
32
|
+
<user>
|
33
|
+
<id>4243</id>
|
34
|
+
<name>John Nunemaker</name>
|
35
|
+
<screen_name>jnunemaker</screen_name>
|
36
|
+
<location>Mishawaka, IN, US</location>
|
37
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
38
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
39
|
+
<url>http://addictedtonew.com</url>
|
40
|
+
<protected>false</protected>
|
41
|
+
<followers_count>486</followers_count>
|
42
|
+
</user>
|
43
|
+
</status>
|
44
|
+
<status>
|
45
|
+
<created_at>Sat Aug 09 01:36:41 +0000 2008</created_at>
|
46
|
+
<id>882126691</id>
|
47
|
+
<text>Steph is driving Sally for the first time. I'm proud of her.</text>
|
48
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
49
|
+
<truncated>false</truncated>
|
50
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
51
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
52
|
+
<favorited></favorited>
|
53
|
+
<user>
|
54
|
+
<id>4243</id>
|
55
|
+
<name>John Nunemaker</name>
|
56
|
+
<screen_name>jnunemaker</screen_name>
|
57
|
+
<location>Mishawaka, IN, US</location>
|
58
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
59
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
60
|
+
<url>http://addictedtonew.com</url>
|
61
|
+
<protected>false</protected>
|
62
|
+
<followers_count>486</followers_count>
|
63
|
+
</user>
|
64
|
+
</status>
|
65
|
+
<status>
|
66
|
+
<created_at>Fri Aug 08 22:21:21 +0000 2008</created_at>
|
67
|
+
<id>881987762</id>
|
68
|
+
<text>@ijonas - what are you making with couchdb, ruby and httparty?</text>
|
69
|
+
<source>web</source>
|
70
|
+
<truncated>false</truncated>
|
71
|
+
<in_reply_to_status_id>881947237</in_reply_to_status_id>
|
72
|
+
<in_reply_to_user_id>1000471</in_reply_to_user_id>
|
73
|
+
<favorited></favorited>
|
74
|
+
<user>
|
75
|
+
<id>4243</id>
|
76
|
+
<name>John Nunemaker</name>
|
77
|
+
<screen_name>jnunemaker</screen_name>
|
78
|
+
<location>Mishawaka, IN, US</location>
|
79
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
80
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
81
|
+
<url>http://addictedtonew.com</url>
|
82
|
+
<protected>false</protected>
|
83
|
+
<followers_count>486</followers_count>
|
84
|
+
</user>
|
85
|
+
</status>
|
86
|
+
<status>
|
87
|
+
<created_at>Fri Aug 08 14:20:14 +0000 2008</created_at>
|
88
|
+
<id>881535796</id>
|
89
|
+
<text>@oaknd1 - delete it off phone and iTunes.</text>
|
90
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
91
|
+
<truncated>false</truncated>
|
92
|
+
<in_reply_to_status_id>881526234</in_reply_to_status_id>
|
93
|
+
<in_reply_to_user_id>3038211</in_reply_to_user_id>
|
94
|
+
<favorited></favorited>
|
95
|
+
<user>
|
96
|
+
<id>4243</id>
|
97
|
+
<name>John Nunemaker</name>
|
98
|
+
<screen_name>jnunemaker</screen_name>
|
99
|
+
<location>Mishawaka, IN, US</location>
|
100
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
101
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
102
|
+
<url>http://addictedtonew.com</url>
|
103
|
+
<protected>false</protected>
|
104
|
+
<followers_count>486</followers_count>
|
105
|
+
</user>
|
106
|
+
</status>
|
107
|
+
<status>
|
108
|
+
<created_at>Fri Aug 08 14:07:29 +0000 2008</created_at>
|
109
|
+
<id>881522394</id>
|
110
|
+
<text>Listening to U2 "beautiful day" in honor of it being such a beautiful day.</text>
|
111
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
112
|
+
<truncated>false</truncated>
|
113
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
114
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
115
|
+
<favorited></favorited>
|
116
|
+
<user>
|
117
|
+
<id>4243</id>
|
118
|
+
<name>John Nunemaker</name>
|
119
|
+
<screen_name>jnunemaker</screen_name>
|
120
|
+
<location>Mishawaka, IN, US</location>
|
121
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
122
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
123
|
+
<url>http://addictedtonew.com</url>
|
124
|
+
<protected>false</protected>
|
125
|
+
<followers_count>486</followers_count>
|
126
|
+
</user>
|
127
|
+
</status>
|
128
|
+
<status>
|
129
|
+
<created_at>Fri Aug 08 14:06:44 +0000 2008</created_at>
|
130
|
+
<id>881521592</id>
|
131
|
+
<text>@lizsmc1 - hi! (just passed her on the road)</text>
|
132
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
133
|
+
<truncated>false</truncated>
|
134
|
+
<in_reply_to_status_id>881519558</in_reply_to_status_id>
|
135
|
+
<in_reply_to_user_id>11485452</in_reply_to_user_id>
|
136
|
+
<favorited></favorited>
|
137
|
+
<user>
|
138
|
+
<id>4243</id>
|
139
|
+
<name>John Nunemaker</name>
|
140
|
+
<screen_name>jnunemaker</screen_name>
|
141
|
+
<location>Mishawaka, IN, US</location>
|
142
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
143
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
144
|
+
<url>http://addictedtonew.com</url>
|
145
|
+
<protected>false</protected>
|
146
|
+
<followers_count>486</followers_count>
|
147
|
+
</user>
|
148
|
+
</status>
|
149
|
+
<status>
|
150
|
+
<created_at>Fri Aug 08 13:59:35 +0000 2008</created_at>
|
151
|
+
<id>881514030</id>
|
152
|
+
<text>Beautiful day for a motorcycle ride.</text>
|
153
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
154
|
+
<truncated>false</truncated>
|
155
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
156
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
157
|
+
<favorited></favorited>
|
158
|
+
<user>
|
159
|
+
<id>4243</id>
|
160
|
+
<name>John Nunemaker</name>
|
161
|
+
<screen_name>jnunemaker</screen_name>
|
162
|
+
<location>Mishawaka, IN, US</location>
|
163
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
164
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
165
|
+
<url>http://addictedtonew.com</url>
|
166
|
+
<protected>false</protected>
|
167
|
+
<followers_count>486</followers_count>
|
168
|
+
</user>
|
169
|
+
</status>
|
170
|
+
<status>
|
171
|
+
<created_at>Fri Aug 08 13:45:21 +0000 2008</created_at>
|
172
|
+
<id>881499439</id>
|
173
|
+
<text>@lizamc1 - no way! Politos will be missed. I remember eating a whole garlic pizza there with Joe.</text>
|
174
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
175
|
+
<truncated>false</truncated>
|
176
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
177
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
178
|
+
<favorited></favorited>
|
179
|
+
<user>
|
180
|
+
<id>4243</id>
|
181
|
+
<name>John Nunemaker</name>
|
182
|
+
<screen_name>jnunemaker</screen_name>
|
183
|
+
<location>Mishawaka, IN, US</location>
|
184
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
185
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
186
|
+
<url>http://addictedtonew.com</url>
|
187
|
+
<protected>false</protected>
|
188
|
+
<followers_count>486</followers_count>
|
189
|
+
</user>
|
190
|
+
</status>
|
191
|
+
<status>
|
192
|
+
<created_at>Fri Aug 08 13:41:50 +0000 2008</created_at>
|
193
|
+
<id>881496024</id>
|
194
|
+
<text>Riding my motorcyle to campus. Using the library basement for a meeting.</text>
|
195
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
196
|
+
<truncated>false</truncated>
|
197
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
198
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
199
|
+
<favorited></favorited>
|
200
|
+
<user>
|
201
|
+
<id>4243</id>
|
202
|
+
<name>John Nunemaker</name>
|
203
|
+
<screen_name>jnunemaker</screen_name>
|
204
|
+
<location>Mishawaka, IN, US</location>
|
205
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
206
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
207
|
+
<url>http://addictedtonew.com</url>
|
208
|
+
<protected>false</protected>
|
209
|
+
<followers_count>486</followers_count>
|
210
|
+
</user>
|
211
|
+
</status>
|
212
|
+
<status>
|
213
|
+
<created_at>Thu Aug 07 22:52:20 +0000 2008</created_at>
|
214
|
+
<id>880896190</id>
|
215
|
+
<text>Scraping super glue off my finger with a knife.</text>
|
216
|
+
<source>web</source>
|
217
|
+
<truncated>false</truncated>
|
218
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
219
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
220
|
+
<favorited></favorited>
|
221
|
+
<user>
|
222
|
+
<id>4243</id>
|
223
|
+
<name>John Nunemaker</name>
|
224
|
+
<screen_name>jnunemaker</screen_name>
|
225
|
+
<location>Mishawaka, IN, US</location>
|
226
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
227
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
228
|
+
<url>http://addictedtonew.com</url>
|
229
|
+
<protected>false</protected>
|
230
|
+
<followers_count>486</followers_count>
|
231
|
+
</user>
|
232
|
+
</status>
|
233
|
+
<status>
|
234
|
+
<created_at>Thu Aug 07 22:14:35 +0000 2008</created_at>
|
235
|
+
<id>880866160</id>
|
236
|
+
<text>So cold...Starbucks north side, you win the day, but I shall bring a sweatshirt to our next battle!</text>
|
237
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
238
|
+
<truncated>false</truncated>
|
239
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
240
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
241
|
+
<favorited></favorited>
|
242
|
+
<user>
|
243
|
+
<id>4243</id>
|
244
|
+
<name>John Nunemaker</name>
|
245
|
+
<screen_name>jnunemaker</screen_name>
|
246
|
+
<location>Mishawaka, IN, US</location>
|
247
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
248
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
249
|
+
<url>http://addictedtonew.com</url>
|
250
|
+
<protected>false</protected>
|
251
|
+
<followers_count>486</followers_count>
|
252
|
+
</user>
|
253
|
+
</status>
|
254
|
+
<status>
|
255
|
+
<created_at>Thu Aug 07 17:25:40 +0000 2008</created_at>
|
256
|
+
<id>880610064</id>
|
257
|
+
<text>Headed home for a bit to get my headphones and then to the north side to meet @orderedlist.</text>
|
258
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
259
|
+
<truncated>false</truncated>
|
260
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
261
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
262
|
+
<favorited></favorited>
|
263
|
+
<user>
|
264
|
+
<id>4243</id>
|
265
|
+
<name>John Nunemaker</name>
|
266
|
+
<screen_name>jnunemaker</screen_name>
|
267
|
+
<location>Mishawaka, IN, US</location>
|
268
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
269
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
270
|
+
<url>http://addictedtonew.com</url>
|
271
|
+
<protected>false</protected>
|
272
|
+
<followers_count>485</followers_count>
|
273
|
+
</user>
|
274
|
+
</status>
|
275
|
+
<status>
|
276
|
+
<created_at>Thu Aug 07 17:15:59 +0000 2008</created_at>
|
277
|
+
<id>880600278</id>
|
278
|
+
<text>Panera wifi, why do you hate me?</text>
|
279
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
280
|
+
<truncated>false</truncated>
|
281
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
282
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
283
|
+
<favorited></favorited>
|
284
|
+
<user>
|
285
|
+
<id>4243</id>
|
286
|
+
<name>John Nunemaker</name>
|
287
|
+
<screen_name>jnunemaker</screen_name>
|
288
|
+
<location>Mishawaka, IN, US</location>
|
289
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
290
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
291
|
+
<url>http://addictedtonew.com</url>
|
292
|
+
<protected>false</protected>
|
293
|
+
<followers_count>485</followers_count>
|
294
|
+
</user>
|
295
|
+
</status>
|
296
|
+
<status>
|
297
|
+
<created_at>Thu Aug 07 15:46:25 +0000 2008</created_at>
|
298
|
+
<id>880509577</id>
|
299
|
+
<text>At panera. Turned my alarm off this morning and woke up late. Oh well.</text>
|
300
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
301
|
+
<truncated>false</truncated>
|
302
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
303
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
304
|
+
<favorited></favorited>
|
305
|
+
<user>
|
306
|
+
<id>4243</id>
|
307
|
+
<name>John Nunemaker</name>
|
308
|
+
<screen_name>jnunemaker</screen_name>
|
309
|
+
<location>Mishawaka, IN, US</location>
|
310
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
311
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
312
|
+
<url>http://addictedtonew.com</url>
|
313
|
+
<protected>false</protected>
|
314
|
+
<followers_count>485</followers_count>
|
315
|
+
</user>
|
316
|
+
</status>
|
317
|
+
<status>
|
318
|
+
<created_at>Thu Aug 07 15:01:35 +0000 2008</created_at>
|
319
|
+
<id>880463746</id>
|
320
|
+
<text>@kloh I remember days like that. Exhausting. Also, NullRiver said to sync again, uninstall app from phone and then resync app. Evidently ...</text>
|
321
|
+
<source>web</source>
|
322
|
+
<truncated>true</truncated>
|
323
|
+
<in_reply_to_status_id>880432701</in_reply_to_status_id>
|
324
|
+
<in_reply_to_user_id>10193732</in_reply_to_user_id>
|
325
|
+
<favorited></favorited>
|
326
|
+
<user>
|
327
|
+
<id>4243</id>
|
328
|
+
<name>John Nunemaker</name>
|
329
|
+
<screen_name>jnunemaker</screen_name>
|
330
|
+
<location>Mishawaka, IN, US</location>
|
331
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
332
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
333
|
+
<url>http://addictedtonew.com</url>
|
334
|
+
<protected>false</protected>
|
335
|
+
<followers_count>485</followers_count>
|
336
|
+
</user>
|
337
|
+
</status>
|
338
|
+
<status>
|
339
|
+
<created_at>Thu Aug 07 02:52:38 +0000 2008</created_at>
|
340
|
+
<id>879986739</id>
|
341
|
+
<text>@kloh - I haven't updated my OS so I'm wondering how apple could have made the app stop working. I did contact NullRiver support just no ...</text>
|
342
|
+
<source>web</source>
|
343
|
+
<truncated>true</truncated>
|
344
|
+
<in_reply_to_status_id>879980813</in_reply_to_status_id>
|
345
|
+
<in_reply_to_user_id>10193732</in_reply_to_user_id>
|
346
|
+
<favorited></favorited>
|
347
|
+
<user>
|
348
|
+
<id>4243</id>
|
349
|
+
<name>John Nunemaker</name>
|
350
|
+
<screen_name>jnunemaker</screen_name>
|
351
|
+
<location>Mishawaka, IN, US</location>
|
352
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
353
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
354
|
+
<url>http://addictedtonew.com</url>
|
355
|
+
<protected>false</protected>
|
356
|
+
<followers_count>486</followers_count>
|
357
|
+
</user>
|
358
|
+
</status>
|
359
|
+
<status>
|
360
|
+
<created_at>Thu Aug 07 02:38:58 +0000 2008</created_at>
|
361
|
+
<id>879976045</id>
|
362
|
+
<text>@jerry - i went with the pdf download.</text>
|
363
|
+
<source>web</source>
|
364
|
+
<truncated>false</truncated>
|
365
|
+
<in_reply_to_status_id>879878196</in_reply_to_status_id>
|
366
|
+
<in_reply_to_user_id>613</in_reply_to_user_id>
|
367
|
+
<favorited></favorited>
|
368
|
+
<user>
|
369
|
+
<id>4243</id>
|
370
|
+
<name>John Nunemaker</name>
|
371
|
+
<screen_name>jnunemaker</screen_name>
|
372
|
+
<location>Mishawaka, IN, US</location>
|
373
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
374
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
375
|
+
<url>http://addictedtonew.com</url>
|
376
|
+
<protected>false</protected>
|
377
|
+
<followers_count>486</followers_count>
|
378
|
+
</user>
|
379
|
+
</status>
|
380
|
+
<status>
|
381
|
+
<created_at>Thu Aug 07 02:31:26 +0000 2008</created_at>
|
382
|
+
<id>879969851</id>
|
383
|
+
<text>@kloh - it worked at home for multiple tests and just stopped when I acyltually needed it.</text>
|
384
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
385
|
+
<truncated>false</truncated>
|
386
|
+
<in_reply_to_status_id>879968483</in_reply_to_status_id>
|
387
|
+
<in_reply_to_user_id>10193732</in_reply_to_user_id>
|
388
|
+
<favorited></favorited>
|
389
|
+
<user>
|
390
|
+
<id>4243</id>
|
391
|
+
<name>John Nunemaker</name>
|
392
|
+
<screen_name>jnunemaker</screen_name>
|
393
|
+
<location>Mishawaka, IN, US</location>
|
394
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
395
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
396
|
+
<url>http://addictedtonew.com</url>
|
397
|
+
<protected>false</protected>
|
398
|
+
<followers_count>486</followers_count>
|
399
|
+
</user>
|
400
|
+
</status>
|
401
|
+
<status>
|
402
|
+
<created_at>Thu Aug 07 01:18:28 +0000 2008</created_at>
|
403
|
+
<id>879913748</id>
|
404
|
+
<text>Netshare will no longer start up for me. Of course it borks the first time I actually want to use it.</text>
|
405
|
+
<source><a href="http://help.twitter.com/index.php?pg=kb.page&id=75">txt</a></source>
|
406
|
+
<truncated>false</truncated>
|
407
|
+
<in_reply_to_status_id></in_reply_to_status_id>
|
408
|
+
<in_reply_to_user_id></in_reply_to_user_id>
|
409
|
+
<favorited></favorited>
|
410
|
+
<user>
|
411
|
+
<id>4243</id>
|
412
|
+
<name>John Nunemaker</name>
|
413
|
+
<screen_name>jnunemaker</screen_name>
|
414
|
+
<location>Mishawaka, IN, US</location>
|
415
|
+
<description>Loves his wife, ruby, notre dame football and iu basketball</description>
|
416
|
+
<profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg</profile_image_url>
|
417
|
+
<url>http://addictedtonew.com</url>
|
418
|
+
<protected>false</protected>
|
419
|
+
<followers_count>486</followers_count>
|
420
|
+
</user>
|
421
|
+
</status>
|
422
|
+
</statuses>
|