ruby-daj 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 186bd3f05c510fd6fea8356fa573ba7959a9053e
4
+ data.tar.gz: 79b222a670ff3339a0a0e17dfc8174869c4454d2
5
+ SHA512:
6
+ metadata.gz: c01ec5b40de9c1cb87a3aebe3d7b2da4d97e66c3cef43d1a221747f7a1f1e271e6365c7a92c88e63675be0da5ba7395d4b8b9199ccc18d858a12289a49e3a185
7
+ data.tar.gz: f05ff4b49a21ccd277cfffb01e2b173f56ce99f49ff3c176e602fae81901d147f74c5ba5dbace1a11fd230e1d9607dfe26cd92da0fc580f0b6211337d959199f
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
@@ -0,0 +1,113 @@
1
+ # daj
2
+
3
+ Are you terminally annoyed by the number of unaesthetic lines you have to write when the only thing you need is just reading and parsing some fracking data?
4
+
5
+ Well if this is the case, **daj** is made for you!
6
+
7
+ **daj**'s philosophy is to enable you to read and write popular data formats in one simplistic line.
8
+
9
+ No more of the following nonsense:
10
+
11
+ ```ruby
12
+ import codecs
13
+ import json
14
+
15
+ with codecs.open('path/to/your-fracking-data.json', 'r', encoding='utf-8') as jf:
16
+ data = json.load(jf)
17
+ ```
18
+
19
+ Now, you just write:
20
+
21
+ ```ruby
22
+ from daj import daj
23
+
24
+ data = daj < 'path/to/your-fracking-data.json'
25
+ ```
26
+
27
+ **daj** is your quick & dirty scripting companion. No more annoying boilerplate code: you start coding things that matter right now!
28
+
29
+ ## Installation
30
+
31
+ With pip
32
+
33
+ ```ruby
34
+ gem 'ruby-daj'
35
+ ```
36
+ or
37
+
38
+ ```ruby
39
+ gem install ruby-daj
40
+ ```
41
+
42
+
43
+ To install the latest dev version
44
+
45
+ ```ruby
46
+ gem 'ruby-daj', git: "git://github.com/gtroppee/ruby-daj.git"
47
+ ```
48
+ or
49
+
50
+ ```ruby
51
+ gem specific_install -l git://github.com/gtroppee/ruby-daj.git
52
+ ```
53
+
54
+ ## Formats supported
55
+
56
+ * plain text
57
+ * json
58
+ * yaml
59
+ * csv
60
+ * tsv
61
+
62
+ ## Reading
63
+ Note that if you do not provide a method to **daj**, this one will try to guess your format by analyzing the file's extension.
64
+
65
+ So if you have a twisted mind and like to name csv files `table.json`, well first of all you are a sneaky bastard, second, just use the proper **daj** method.
66
+
67
+ ```ruby
68
+ # Guessing the format
69
+ data = daj < 'file.json'
70
+
71
+ # Will also work with raw text
72
+ data = daj < 'file.txt'
73
+
74
+ # Using daj methods
75
+ data = daj.json < 'file.json'
76
+ data = daj.yml < 'file.yml'
77
+ data = daj.csv < 'file.csv'
78
+ data = daj.tsv < 'file.tsv'
79
+
80
+ # Needing headers for your neat CSV files?
81
+ data = daj.csvh < 'file.csv'
82
+ data = daj.tsvh < 'file.tsv'
83
+ ```
84
+
85
+ ## Writing
86
+ As for reading, **daj** will try to guess the correct format for your data based on the extension of the file.
87
+
88
+ ```ruby
89
+ # Writing some data
90
+ daj(data) > 'file.json'
91
+
92
+ # Will also work with raw text
93
+ daj(data) > 'file.txt'
94
+
95
+ # Using daj methods
96
+ daj.json(data) > 'file.json'
97
+ daj.yml(data) > 'file.yml'
98
+
99
+ # If you want to ouput a pretty printed json
100
+ daj.pjson(data) > 'prettyfile.json'
101
+
102
+ # For csv, you can give an array of arrays or an array of objects
103
+ # If an array of objects is given, daj will output a csv with headers.
104
+ daj.csv(data) > 'file.csv'
105
+ daj.tsv(data) > 'file.tsv'
106
+ ```
107
+
108
+ ## Disclaimers
109
+ **daj** is clearly orientated toward quick & dirty data processing. This is probably a bad idea to use it in a production context and I would not vouch for that.
110
+ **ruby-daj** is directly inspired by [python-daj](https://github.com/Yomguithereal/python-daj)
111
+
112
+ ## Contribution
113
+ Contribution are more than welcome, be sure to add relevant unit tests and pass them all before subitting any code.
@@ -0,0 +1,14 @@
1
+ module RubyDaj
2
+ FORMATS = %w(json yml csv csvh tsv tsvh)
3
+ def self.root
4
+ File.dirname __dir__
5
+ end
6
+ end
7
+
8
+ require 'json'
9
+ require 'yaml'
10
+ require 'csv'
11
+ require_relative 'ruby-daj/helpers'
12
+ require_relative 'ruby-daj/reader'
13
+ require_relative 'ruby-daj/writer'
14
+ require_relative 'ruby-daj/daj'
@@ -0,0 +1,29 @@
1
+ # Main class
2
+ #===========
3
+ class Daj
4
+ attr_accessor :kind
5
+
6
+ # Constructor
7
+ def initialize(data = nil)
8
+ @data = data
9
+ end
10
+
11
+ # Less than operator as read file
12
+ def <(filename)
13
+ ext = kind || extension(filename)
14
+ Reader.new.read(ext, filename)
15
+ end
16
+
17
+ def >(filename)
18
+ ext = kind || extension(filename)
19
+ Writer.new(@data).write(ext, filename)
20
+ end
21
+
22
+ # Methods
23
+ #--------
24
+ RubyDaj::FORMATS.each do |format|
25
+ define_method(format) do |data = nil|
26
+ daj = Daj.new(data); daj.kind = format; daj
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ def extension(filename)
2
+ File.extname(filename).gsub('.', '')
3
+ end
4
+
5
+ def daj(data = nil)
6
+ Daj.new(data)
7
+ end
@@ -0,0 +1,45 @@
1
+ class Reader
2
+
3
+ # Reading
4
+ #--------
5
+
6
+ # Reader abstract
7
+ def read(ext, filename)
8
+ RubyDaj::FORMATS.include?(ext) ? send(:"read_#{ext}", filename) : read_plain_text(filename)
9
+ end
10
+
11
+ def read_plain_text(filename)
12
+ File.read(filename).chomp
13
+ end
14
+
15
+ def read_json(filename)
16
+ json = JSON.parse(File.read(filename))
17
+ json.kind_of?(Array) ? json[0] : json
18
+ end
19
+
20
+ def read_yml(filename)
21
+ YAML.load_file(filename)
22
+ end
23
+
24
+ def read_csv(filename)
25
+ CSV.read(filename)
26
+ end
27
+
28
+ def read_csvh(filename)
29
+ CSV.read(filename, headers: true).map{|row| Hash[row.map{|col, row| [col, row]}]}
30
+ end
31
+
32
+ def read_tsv(filename)
33
+ # TODO Refactor this ugliness
34
+ CSV.read(filename, col_sep: "\t").map{|x| x.map{|x| x.split(" ")}}.map(&:flatten)
35
+ end
36
+
37
+ def read_tsvh(filename)
38
+ CSV.read(filename, col_sep: "\t", headers: true).map do |row|
39
+ headers = row.headers[0].split(' ')
40
+ fields = row.fields[0].split(' ')
41
+ Hash[headers.each_with_index.map{|_, index| [headers[index], fields[index]]}]
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,57 @@
1
+ class Writer
2
+
3
+ def initialize(data)
4
+ if data.nil?
5
+ raise ArgumentError, 'Data is required in order to perform this operation. Please use the following form "daj(your_data) > your_file" and everything should be fine.'
6
+ else
7
+ @data = data
8
+ end
9
+ end
10
+
11
+ # Writing
12
+ #--------
13
+
14
+ # Call operator as writer
15
+ def write(ext, filename)
16
+ ext = @kind || ext
17
+ RubyDaj::FORMATS.include?(ext) ? send(:"write_#{ext}", filename) : write_plain_text(filename)
18
+ end
19
+
20
+ def write_plain_text(filename, encoding = 'utf-8')
21
+ File.open(filename, "w:#{encoding}") {|f| f.puts @data }
22
+ end
23
+
24
+ def write_json(filename)
25
+ File.open(filename, "w") {|f| f.puts @data.to_json }
26
+ end
27
+
28
+ def write_yml(filename)
29
+ File.open(filename, "w") {|f| f.puts @data.to_yaml }
30
+ end
31
+
32
+ def write_csv(filename)
33
+ CSV.open(filename, "w") do |csv|
34
+ @data.each {|data| csv << data}
35
+ end
36
+ end
37
+
38
+ def write_csvh(filename)
39
+ CSV.open(filename, "w") do |csv|
40
+ csv << @data.first.keys # adds the attributes name on the first line
41
+ @data.each {|hash| csv << hash.values}
42
+ end
43
+ end
44
+
45
+ def write_tsv(filename)
46
+ CSV.open(filename, "w", col_sep: "\t") do |tsv|
47
+ @data.each {|data| tsv << data}
48
+ end
49
+ end
50
+
51
+ def write_tsvh(filename)
52
+ CSV.open(filename, "w", col_sep: "\t") do |tsv|
53
+ tsv << @data.first.keys # adds the attributes name on the first line
54
+ @data.each {|hash| tsv << hash.values}
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ describe Reader do
3
+
4
+ it '#read_plain_text' do
5
+ data = "Hello World !"
6
+ expect(data).to eq daj < resources_path('hello.txt')
7
+ end
8
+
9
+ it '#read_json' do
10
+ data = {"hello"=>"world", "colors"=>["yellow", "blue"]}
11
+ expect(data).to eq daj < resources_path('hello.json')
12
+ expect(data).to eq daj.json < resources_path('hello.json')
13
+ end
14
+
15
+ it '#read_yml' do
16
+ data = {"hello"=>"world", "colors"=>["yellow", "blue"]}
17
+ expect(data).to eq daj < resources_path('hello.yml')
18
+ expect(data).to eq daj.yml < resources_path('hello.yml')
19
+ end
20
+
21
+ it '#read_csv' do
22
+ names = [['Joe', 'Dagger'], ['Elena', 'Ashcroft']]
23
+ hnames = [{'Firstname'=>'Joe', 'Lastname'=>'Dagger'}, {'Firstname'=>'Elena', 'Lastname'=>'Ashcroft'}]
24
+ expect(names).to eq daj < resources_path('names.csv')
25
+ expect(names).to eq daj.csv < resources_path('names.csv')
26
+ expect(hnames).to eq daj.csvh < resources_path('hnames.csv')
27
+ end
28
+
29
+ it '#read_tsv' do
30
+ names = [['Joe', 'Dagger'], ['Elena', 'Ashcroft']]
31
+ hnames = [{'Firstname'=>'Joe', 'Lastname'=>'Dagger'}, {'Firstname'=>'Elena', 'Lastname'=>'Ashcroft'}]
32
+ expect(names).to eq daj < resources_path('names.tsv')
33
+ expect(names).to eq daj.tsv < resources_path('names.tsv')
34
+ expect(hnames).to eq daj.tsvh < resources_path('hnames.tsv')
35
+ end
36
+
37
+ end
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ require 'utilities'
3
+ require 'pry'
4
+ Bundler.setup
5
+
6
+ require 'ruby-daj' # and any other gems you need
7
+
8
+ RSpec.configure do |config|
9
+ # some (optional) config here
10
+ end
@@ -0,0 +1,7 @@
1
+ def resources_path(file)
2
+ "#{RubyDaj.root}/spec/resources/#{file}"
3
+ end
4
+
5
+ def delete_resources(*filenames)
6
+ filenames.each{|filename| FileUtils.remove_file(resources_path(filename))}
7
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+ describe Writer do
3
+
4
+ it '#write_plain_data' do
5
+ data = "Hello, world!"
6
+ daj(data) > resources_path('test_hello.txt')
7
+ expect(data).to eq daj < resources_path('test_hello.txt')
8
+
9
+ delete_resources('test_hello.txt')
10
+ end
11
+
12
+ it '#write_json' do
13
+ data1 = {'hello' => 'world'}
14
+ data2 = {hello: 'world'}
15
+
16
+ daj(data1) > resources_path('test_hello1.json')
17
+ daj(data2) > resources_path('test_hello2.json')
18
+
19
+ expect(data1).to eq daj < resources_path('test_hello1.json')
20
+ expect(data1).to eq daj.json < resources_path('test_hello2.json')
21
+
22
+ delete_resources('test_hello1.json', 'test_hello2.json')
23
+ end
24
+
25
+ it '#write_yaml' do
26
+ data = {"hello"=>"world", "colors"=>["yellow", "blue"]}
27
+ daj(data) > resources_path('test_hello.yml')
28
+ expect(data).to eq daj < resources_path('test_hello.yml')
29
+
30
+ delete_resources('test_hello.yml')
31
+ end
32
+
33
+ it '#write_csv' do
34
+ data = [['Joe', 'Dagger'], ['Elena', 'Ashcroft']]
35
+ daj(data) > resources_path('test_names.csv')
36
+ expect(data).to eq daj < resources_path('test_names.csv')
37
+
38
+ delete_resources('test_names.csv')
39
+ end
40
+
41
+ it '#write_csvh' do
42
+ data = [{'Firstname'=>'Joe', 'Lastname'=>'Dagger'}, {'Firstname'=>'Elena', 'Lastname'=>'Ashcroft'}]
43
+ daj.csvh(data) > resources_path('test_hnames.csv')
44
+ expect(data).to eq daj.csvh < resources_path('test_hnames.csv')
45
+
46
+ delete_resources('test_hnames.csv')
47
+ end
48
+
49
+ it '#write_tsv' do
50
+ data = [['Joe', 'Dagger'], ['Elena', 'Ashcroft']]
51
+ daj(data) > resources_path('test_names.tsv')
52
+ expect(data).to eq daj < resources_path('test_names.tsv')
53
+
54
+ delete_resources('test_names.tsv')
55
+ end
56
+
57
+ # it '#write_tsvh' do
58
+ # data = [{'Firstname'=>'Joe', 'Lastname'=>'Dagger'}, {'Firstname'=>'Elena', 'Lastname'=>'Ashcroft'}]
59
+ # daj.tsvh(data) > resources_path('test_hnames.tsv')
60
+ # expect(data).to eq daj.tsvh < resources_path('test_hnames.tsv')
61
+
62
+ # delete_resources('test_hnames.tsv')
63
+ # end
64
+
65
+ it 'should raise an exception if no data is provided' do
66
+ expect { daj.csvh > resources_path('test_hnames.csv') }.to raise_error
67
+ end
68
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-daj
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Guillaume Troppée
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email: gtroppee@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - README.md
34
+ - Gemfile
35
+ - spec/reader_spec.rb
36
+ - spec/spec_helper.rb
37
+ - spec/utilities.rb
38
+ - spec/writer_spec.rb
39
+ - lib/ruby-daj/daj.rb
40
+ - lib/ruby-daj/helpers.rb
41
+ - lib/ruby-daj/reader.rb
42
+ - lib/ruby-daj/writer.rb
43
+ - lib/ruby-daj.rb
44
+ homepage: http://rubygems.org/gems/ruby-daj
45
+ licenses:
46
+ - MIT
47
+ metadata: {}
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 2.1.11
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: Read and write data in ruby without further ado
68
+ test_files: []
69
+ has_rdoc: