ruby-daj 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: