sweetie 0.1.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/.rspec +3 -0
- data/.travis.yml +3 -2
- data/Gemfile +5 -0
- data/README.md +73 -16
- data/lib/sweetie.rb +2 -3
- data/lib/sweetie/bitbucket.rb +143 -0
- data/lib/sweetie/conversion.rb +86 -0
- data/lib/sweetie/helper.rb +85 -0
- data/lib/sweetie/version.rb +4 -0
- data/spec/source/bitbucket/user_changeset.json +30 -0
- data/spec/source/bitbucket/user_changeset_expectation.txt +1 -0
- data/spec/source/bitbucket/user_repositories.json +143 -0
- data/spec/sweetie_bitbucket_spec.rb +66 -0
- data/spec/sweetie_conversion_spec.rb +31 -0
- data/sweetie.gemspec +22 -18
- metadata +109 -112
- data/doc/Sweetie.html +0 -125
- data/doc/_index.html +0 -121
- data/doc/class_list.html +0 -47
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -53
- data/doc/css/style.css +0 -320
- data/doc/file.README.html +0 -95
- data/doc/file_list.html +0 -49
- data/doc/frames.html +0 -13
- data/doc/index.html +0 -95
- data/doc/js/app.js +0 -205
- data/doc/js/full_list.js +0 -150
- data/doc/js/jquery.js +0 -16
- data/doc/method_list.html +0 -126
- data/doc/top-level-namespace.html +0 -103
- data/spec/source/site/css/config.rb +0 -24
- data/spec/source/site/css/sass/site.sass +0 -180
- data/spec/source/site/css/stylesheets/iphone.css +0 -17
- data/spec/source/site/css/stylesheets/site.css +0 -246
- data/spec/source/site/css/stylesheets/syntax.css +0 -60
- data/spec/source/site/js/FancyZoom.js +0 -761
- data/spec/source/site/js/FancyZoomHTML.js +0 -318
- data/spec/source/site/test/config.rb +0 -24
- data/spec/source/site/test/sass/ie.scss +0 -5
- data/spec/source/site/test/sass/print.scss +0 -3
- data/spec/source/site/test/sass/screen.scss +0 -6
- data/spec/source/site/test/stylesheets/ie.css +0 -5
- data/spec/source/site/test/stylesheets/print.css +0 -3
- data/spec/source/site/test/stylesheets/screen.css +0 -69
- data/spec/sweetie_spec.rb +0 -30
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.travis.yml
CHANGED
@@ -1,2 +1,3 @@
|
|
1
|
-
|
2
|
-
- 1.9.
|
1
|
+
rbenv:
|
2
|
+
- 1.9.2-p290
|
3
|
+
|
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -1,26 +1,83 @@
|
|
1
|
-
Sweetie is a plugin for [jekyll](https://github.com/mojombo/jekyll) to count all links, images,
|
1
|
+
Sweetie is a plugin for [jekyll](https://github.com/mojombo/jekyll) to count all links, images,
|
2
|
+
pages, and the last build time on a jekyll site. You can then use this information at a any place in
|
3
|
+
your jekyll project.[![Travis](http://travis-ci.org/matthias-guenther/sweetie.png)](http://travis-ci.org/matthias-guenther/sweetie)
|
2
4
|
|
3
5
|
|
4
|
-
##
|
5
|
-
To get the plugin working you must add `build`, `htmlpages`, `images`, and `links` in your `_config.yml` file. _sweetie_ will save the information to this variables. You can then use them everywhere in your page with the liquid snippet for example:
|
6
|
+
## Installation ##
|
6
7
|
|
7
|
-
|
8
|
-
* `{{ site.htmlpages }}`
|
9
|
-
* `{{ site.images }}`
|
10
|
-
* `{{ site.links }}`
|
8
|
+
gem install sweetie
|
11
9
|
|
12
|
-
on all of your pages.
|
13
10
|
|
11
|
+
## Possible usage ##
|
14
12
|
|
15
|
-
|
16
|
-
Put the `sweetie.rb` file in the root of your jekyll project and then run the file to update your `_config.yml`file. To get the right calculated number of html pages, your pages must have the file ending *.html.
|
13
|
+
The easiest way is to add `require 'sweetie'` on the top of your Rakefile.
|
17
14
|
|
15
|
+
Before you build your page, you can run a rake task to update the status information of a page:
|
18
16
|
|
19
|
-
|
20
|
-
|
17
|
+
desc 'write stats in the _config.yml'
|
18
|
+
task :create_stati do
|
19
|
+
Sweetie::Conversion.conversion
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
A similar task can be implemented for the bitbucket repositories:
|
23
|
+
|
24
|
+
desc 'write stats in the _config.yml'
|
25
|
+
task :create_bitbucket do
|
26
|
+
Sweetie::Bitbucket.bitbucket("yourname")
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
## Configuration variables of jekyll ##
|
31
|
+
|
32
|
+
Call the class method `Sweetie::Bitbucket.bitbucket("yourname")` and it will automatically append
|
33
|
+
the `build`, `htmlpages`, `images`, and `links` in your `_config.yml` file. You can then use them
|
34
|
+
everywhere in your page with the liquid snippet for example:
|
35
|
+
|
36
|
+
- `{{ site.build }}`
|
37
|
+
- `{{ site.htmlpages }}`
|
38
|
+
- `{{ site.images }}`
|
39
|
+
- `{{ site.links }}`
|
40
|
+
|
41
|
+
|
42
|
+
## Last changes of bitbucket repository ##
|
43
|
+
|
44
|
+
Call the class method `Sweetie::Bitbucket.bitbucket("yourname")` and it will automatically append
|
45
|
+
the repository name an the last change of the repository in your `_config.yml`. Here is an example:
|
46
|
+
|
47
|
+
git: 2011-10-16
|
48
|
+
pmwiki-twitter-recipe: 2011-10-29
|
49
|
+
|
50
|
+
You can then use this variables in the view of your jekyll project with the liquid template. For
|
51
|
+
example:
|
52
|
+
|
53
|
+
### git ###
|
54
|
+
|
55
|
+
<section class="lastupdate">
|
56
|
+
Last update {{ site.git }}
|
57
|
+
</section>
|
58
|
+
...
|
59
|
+
|
60
|
+
|
61
|
+
### Twitter ###
|
62
|
+
|
63
|
+
<section class="lastupdate">
|
64
|
+
Last update {{ site.pmwiki-twitter-recipe }}
|
65
|
+
</section>
|
66
|
+
...
|
67
|
+
|
68
|
+
will result the following html:
|
69
|
+
|
70
|
+
|
71
|
+
<h3 id="git">Git</h3>
|
72
|
+
|
73
|
+
<section class="lastupdate">
|
74
|
+
Last update 2011-10-16
|
75
|
+
</section>
|
76
|
+
|
77
|
+
|
78
|
+
<h3 id="twitter">Twitter</h3>
|
79
|
+
|
80
|
+
<section class="lastupdate">
|
81
|
+
Last update 2011-10-16
|
82
|
+
</section>
|
26
83
|
|
data/lib/sweetie.rb
CHANGED
@@ -0,0 +1,143 @@
|
|
1
|
+
module Sweetie
|
2
|
+
require 'sweetie/helper'
|
3
|
+
|
4
|
+
class Bitbucket
|
5
|
+
require 'json'
|
6
|
+
@@config = "_config.yml"
|
7
|
+
|
8
|
+
class << self
|
9
|
+
include Sweetie::Helper
|
10
|
+
|
11
|
+
# getter for class variable @@config
|
12
|
+
def config
|
13
|
+
@@config
|
14
|
+
end
|
15
|
+
|
16
|
+
# setter for the class variable @@config
|
17
|
+
def config=(config)
|
18
|
+
@@config = config
|
19
|
+
end
|
20
|
+
|
21
|
+
# Wrapper to start all the other methods
|
22
|
+
# @param [user] a valid bitbucket user
|
23
|
+
def bitbucket(user)
|
24
|
+
# json represetnation of user repositories
|
25
|
+
json_repositories = get_repositories_json(user)
|
26
|
+
|
27
|
+
# get the names of the repositories
|
28
|
+
repositories_names = read_repositories(json_repositories)
|
29
|
+
|
30
|
+
# get the hash with repository-name and last changes
|
31
|
+
repositories_changes_hash = repositories_changes(user, repositories_names)
|
32
|
+
|
33
|
+
# write the repository information in the _config.yml
|
34
|
+
write_repository_changes(repositories_changes_hash)
|
35
|
+
end
|
36
|
+
|
37
|
+
# names of all repositories of a user
|
38
|
+
# @param [json_repositories] repositories in json format
|
39
|
+
# @return array with the names of all repositories of the user
|
40
|
+
def read_repositories(json_repositories)
|
41
|
+
repository_hash = parse_json(json_repositories)
|
42
|
+
repositories_names = []
|
43
|
+
|
44
|
+
repository_hash["repositories"].each do |repo|
|
45
|
+
repositories_names << repo["slug"]
|
46
|
+
end
|
47
|
+
|
48
|
+
repositories_names
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get the last changes for each repository and the name
|
52
|
+
# @param [user] a valid bitbucket user
|
53
|
+
# @param [repositories] array with names of all repositories of a user
|
54
|
+
# @return hash with all the repositories of the user and the last changes
|
55
|
+
def repositories_changes(user, repositories)
|
56
|
+
repositories_lastmodifications = {}
|
57
|
+
repositories.each do |repository|
|
58
|
+
changeset = repository_changeset(user, repository)
|
59
|
+
repositories_lastmodifications.merge(repository_last_modification(repository, changeset))
|
60
|
+
end
|
61
|
+
|
62
|
+
repositories_lastmodifications
|
63
|
+
end
|
64
|
+
|
65
|
+
# Get the last modification of a repository
|
66
|
+
# @param [repository_name] a valid repository name
|
67
|
+
# @param [repository_json] json representation of the repository
|
68
|
+
def repository_last_modification(repository_name, repository_json)
|
69
|
+
changeset_parsed = parse_json(repository_json)
|
70
|
+
timestamp = changeset_parsed["changesets"].last["timestamp"]
|
71
|
+
|
72
|
+
# create the hash
|
73
|
+
{repository_name => parse_timestamp(timestamp)}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Parse JSON file to format be read by ruby
|
77
|
+
def parse_json(file)
|
78
|
+
JSON.parse file
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get the changeset of a repository
|
82
|
+
# @param [user] a valid bitbucket user
|
83
|
+
# @param [repository] a repository of a user
|
84
|
+
# @return information about the repository in json
|
85
|
+
def repository_changeset(user, repository)
|
86
|
+
`curl -s https://api.bitbucket.org/1.0/repositories/#{user}/#{repository}/changesets/`
|
87
|
+
end
|
88
|
+
|
89
|
+
# Get the json representation of each repository of the user
|
90
|
+
# @param [user] a valid bitbucket user
|
91
|
+
# @return json representation of all bitbucket repositories
|
92
|
+
def get_repositories_json(user)
|
93
|
+
`curl -s https://api.bitbucket.org/1.0/users/#{user}/`
|
94
|
+
end
|
95
|
+
|
96
|
+
# Parse timestamp to display only the date ("2011-04-20 11:31:39" will be converted to "2011-04-20")
|
97
|
+
# @param [timestamp] a time display as a string in the 'Time.now' format
|
98
|
+
# @return "yyyy-mm-dd"
|
99
|
+
def parse_timestamp(timestamp)
|
100
|
+
regex = Regexp.new(/(\d+)-(\d+)-(\d+)/)
|
101
|
+
regex.match(timestamp)[0]
|
102
|
+
end
|
103
|
+
|
104
|
+
# Writes the changes into the _config.yml
|
105
|
+
# @param [repositories] a hash with the following scheme {"svn" => "2011-10-26", "pmwiki" => "2011-10-26"}
|
106
|
+
def write_repository_changes(repositories)
|
107
|
+
repositories.each do |repository, last_change|
|
108
|
+
file = File.open(@@config)
|
109
|
+
text = ""
|
110
|
+
match = false
|
111
|
+
while line = file.gets
|
112
|
+
if line.match(/#{repository}/)
|
113
|
+
match = true
|
114
|
+
# create string and replace this line with the new changes
|
115
|
+
text << create_entry(repository, last_change) + "\n"
|
116
|
+
else
|
117
|
+
text << line
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# append the repository if it is not in there
|
122
|
+
text << create_entry(repository, last_change) unless match
|
123
|
+
|
124
|
+
file.close
|
125
|
+
|
126
|
+
write_config(@@config, text)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Create a string representation of a repository entry
|
131
|
+
# @param [repository_name] string contains the name of the repository
|
132
|
+
# @param [last_change] string contains the date of the change
|
133
|
+
# @return a string in the form "<reponame>: <date>"
|
134
|
+
def create_entry(repository_name, last_change)
|
135
|
+
"#{repository_name}: #{last_change}"
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Sweetie
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'sweetie/helper'
|
4
|
+
|
5
|
+
class Conversion
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
@@config = "_config.yml"
|
10
|
+
@@dir = "_site"
|
11
|
+
|
12
|
+
|
13
|
+
include Sweetie::Helper
|
14
|
+
|
15
|
+
# Opens the config file and search after the specified parameters.
|
16
|
+
# It saves the gathered information about the build-date, the links,
|
17
|
+
# the images, and the number of html-pages in the jekyll project.
|
18
|
+
def conversion
|
19
|
+
check_config_and_directory_file(@@config, @@dir)
|
20
|
+
|
21
|
+
file = File.open(@@config)
|
22
|
+
text = ""
|
23
|
+
while line = file.gets
|
24
|
+
if line.match(/build:/)
|
25
|
+
text << "build: #{build_time}\n"
|
26
|
+
elsif line.match(/htmlpages:/)
|
27
|
+
text << "htmlpages: #{count_all_html_pages(@@dir)}\n"
|
28
|
+
elsif line.match(/images:/)
|
29
|
+
text << "images: #{count_all_images(@@dir)}\n"
|
30
|
+
elsif line.match(/links:/)
|
31
|
+
text << "links: #{count_all_links(@@dir)}\n"
|
32
|
+
else
|
33
|
+
text << line
|
34
|
+
end
|
35
|
+
end
|
36
|
+
file.close
|
37
|
+
|
38
|
+
write_config(file, text)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Counts the link of on html page
|
42
|
+
# @param [page] the path of a html page
|
43
|
+
# @return the number of unique links
|
44
|
+
def count_link_of_one_page(page)
|
45
|
+
perform_search_for_single_page('//a', [], page)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Count the images of one html page
|
49
|
+
# @param (see #self.count_link_of_one_page)
|
50
|
+
# @return the number of unique images
|
51
|
+
def count_images_of_one_page(page)
|
52
|
+
perform_search_for_single_page('//img', [], page)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Counts all html pages
|
56
|
+
# @param [Dir] the path of the directory
|
57
|
+
# @return [Fixnum] the number of unique html pages
|
58
|
+
def count_all_html_pages(dir)
|
59
|
+
perform_global_search('//html', [], dir)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Counts all the links of all html pages
|
63
|
+
# @param (see #self.count_all_html_pages)
|
64
|
+
# @return (see #self.count_all_html_pages)
|
65
|
+
def count_all_links(dir)
|
66
|
+
perform_global_search('//a', [], dir)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Counts all the images of all html pages
|
70
|
+
# @param (see #self.count_all_html_pages)
|
71
|
+
# @return (see #self.count_all_html_pages)
|
72
|
+
def count_all_images(dir)
|
73
|
+
perform_global_search('//img', [], dir)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Create the actual build time
|
77
|
+
# @return [String] in the date format mm-dd-yyyy
|
78
|
+
def build_time
|
79
|
+
time = Time.now
|
80
|
+
"#{time.month}-#{time.day}-#{time.year}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Sweetie
|
2
|
+
|
3
|
+
module Helper
|
4
|
+
|
5
|
+
# Traverse the page after the pattern and return the number of occurences on it
|
6
|
+
# @param [pattern] need for nokogiri to parse the html page
|
7
|
+
# @param [array] array to save the results
|
8
|
+
# @param [page] a single page which will be taken for the search
|
9
|
+
def perform_search_for_single_page(pattern, array, page)
|
10
|
+
harvest(pattern, page, array)
|
11
|
+
output_count(array)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Traverse the dir after the pattern and return the number of occurences in the pages
|
15
|
+
# @param [pattern] need for nokogiri to parse the html page
|
16
|
+
# @param [array] array to save the results
|
17
|
+
# @param [dir] the main directory in which the by jekyll generated files are stored
|
18
|
+
def perform_global_search(pattern, array, dir)
|
19
|
+
traverse(pattern, array, dir)
|
20
|
+
output_count(array)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Traverse the jekyll directory and get the information about a specific pattern
|
24
|
+
# @param [pattern] is a string for nokogiri after which the html pages should be parsed
|
25
|
+
# @param [ar] is an empty Array which is used by the harvest method
|
26
|
+
# @param [dir] the directory in which the html files are stored
|
27
|
+
def traverse(pattern, ar, dir)
|
28
|
+
Dir.glob(dir+"/**/*") do |file|
|
29
|
+
next if file == '.' or file == '..' or file.include?("html~")
|
30
|
+
if file.match(/(.*).html/)
|
31
|
+
harvest(pattern, file, ar)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Traverse each html page and gather information about the specified html element
|
37
|
+
# @param [pattern] important for nokogiri
|
38
|
+
# @param [html] the path for the html file
|
39
|
+
# @param [ar] and array which stores all the findings produces by nokogiri
|
40
|
+
def harvest(pattern, html, ar)
|
41
|
+
file = File.open(html)
|
42
|
+
doc = Nokogiri::HTML(file)
|
43
|
+
doc.xpath(pattern).each do |node|
|
44
|
+
if pattern == "//a"
|
45
|
+
ar << node.text
|
46
|
+
elsif pattern == "//img" and ar.include?(node.to_s)
|
47
|
+
elsif pattern == "//img"
|
48
|
+
ar << node.to_s
|
49
|
+
elsif pattern == "//html"
|
50
|
+
ar << node
|
51
|
+
else
|
52
|
+
end
|
53
|
+
end
|
54
|
+
ar
|
55
|
+
end
|
56
|
+
|
57
|
+
# Count the elements
|
58
|
+
# @param [ar] is an array with all the found html parts
|
59
|
+
def output_count(ar)
|
60
|
+
ar.uniq.count # remove duplicates with uniq
|
61
|
+
end
|
62
|
+
|
63
|
+
# Write in the file the text
|
64
|
+
# @param [file] is the _config.yml file of the jekyll project
|
65
|
+
# @param [text] is a multiline string which will be written in the file
|
66
|
+
def write_config(file, text)
|
67
|
+
File.open(file, 'w') do |file|
|
68
|
+
file.puts text
|
69
|
+
file.close
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Check the existence of needed files for sweetie
|
74
|
+
# @param [config] the _config.yml file
|
75
|
+
# @param [dir] the directory of the generated jekyll page
|
76
|
+
def check_config_and_directory_file(config, dir)
|
77
|
+
if !File.exist? config or !Dir.exist? dir
|
78
|
+
raise "Can't find the _config.yml or the _site directory! Please create these files it!"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|