How to fetch schema version using regex? - ruby

I have the following text:
# encoding: UTF-8
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160405090205) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
I need to get 20160405090205 number. How can I get it?
I've tried /version.*[0-9]/, but this captures only version: 20160405090205.

schema = File.read(Rails.root.join('db', 'schema.rb'))
version, *_ = schema.match(/version: (\d+)/m).captures
version # => "20160405090205"
version, *_ = ... is needed here because captures returns an array even when there is a single capture.

You could get it a capture group
string = "ActiveRecord::Schema.define(version: 20160405090205) do"
version = string.match(/version: (\d+)/m).captures.first

Related

How can I use SaveData to write an ASCII file in ParaView 3.98.1?

I am writing an automation script for an old project and I need some help with pvpython from Paraview 3.98.1. The function SaveData() in this version does not exist. I found its implementation here and moved it to my code. How can I save a file as ASCII? Calling it like SaveData(filename, proxy=px, FileType='Ascii') saves my files as binaries (awkward behavior).
I need this version because some of my codes in the scripting pipeline handle very specific vtk files. Using the SaveData() function of the latest versions ended up creating different metadata in my final files, and when I process them it ends up destroying my results. It is easier at the moment to use an older version of Paraview than to modify all my codes.
Edit:
The website is not working now, but it was yesterday. Maybe it is an internal problem? Anyway, the code is attached below.
# -----------------------------------------------------------------------------
def SetProperties(proxy=None, **params):
"""Sets one or more properties of the given pipeline object. If an argument
is not provided, the active source is used. Pass a list of property_name=value
pairs to this function to set property values. For example::
SetProperties(Center=[1, 2, 3], Radius=3.5)
"""
if not proxy:
proxy = active_objects.source
properties = proxy.ListProperties()
for param in params.keys():
pyproxy = servermanager._getPyProxy(proxy)
pyproxy.__setattr__(param, params[param])
# -----------------------------------------------------------------------------
def CreateWriter(filename, proxy=None, **extraArgs):
"""Creates a writer that can write the data produced by the source proxy in
the given file format (identified by the extension). If no source is
provided, then the active source is used. This doesn't actually write the
data, it simply creates the writer and returns it."""
if not filename:
raise RuntimeError ("filename must be specified")
session = servermanager.ActiveConnection.Session
writer_factory = servermanager.vtkSMProxyManager.GetProxyManager().GetWriterFactory()
if writer_factory.GetNumberOfRegisteredPrototypes() == 0:
writer_factory.UpdateAvailableWriters()
if not proxy:
proxy = GetActiveSource()
if not proxy:
raise RuntimeError ("Could not locate source to write")
writer_proxy = writer_factory.CreateWriter(filename, proxy.SMProxy, proxy.Port)
writer_proxy.UnRegister(None)
pyproxy = servermanager._getPyProxy(writer_proxy)
if pyproxy and extraArgs:
SetProperties(pyproxy, **extraArgs)
return pyproxy
# -----------------------------------------------------------------------------
def SaveData(filename, proxy=None, **extraArgs):
"""Save data produced by 'proxy' in a file. If no proxy is specified the
active source is used. Properties to configure the writer can be passed in
as keyword arguments. Example usage::
SaveData("sample.pvtp", source0)
SaveData("sample.csv", FieldAssociation="Points")
"""
writer = CreateWriter(filename, proxy, **extraArgs)
if not writer:
raise RuntimeError ("Could not create writer for specified file or data type")
writer.UpdateVTKObjects()
writer.UpdatePipeline()
del writer
# -----------------------------------------------------------------------------
The question is answered here (also my post). I used SaveData() to save a binary file with the proxy I need and then used DataSetWriter() to change my FileType to ASCII. It is not a beautiful solution since SaveData() is supposed to do that, but it does the job.

how to set command line parameter to BSON::Timestamp

Pls advice how to set command line parametertail_from which will be accepted by below code:
def optail
tail_from = options[:tail_from]
if tail_from.is_a? Time
tail_from = tailer.most_recent_position(tail_from)
end
tailer.tail(:from => tail_from, :filter => options[:oplog_filter])
...
end
It suggested to be Unix Timestamp
but task fails with error:
For mongo databases, tail :from must be a BSON::Timestamp Mongoriver::Assertions::AssertionFailure)
You can create a BSON::Timestamp from a Unix timestamp using its constructor, setting the increment to 0.
Also, the change streams' functionality has been expanded in recent releases and instead of using an oplog tailer you should consider database or cluster level change streams.

How to download Github Raw CSV file using Ruby

I'm trying to grab an updated CSV file, COVID-19, that's posted on GitHub, but I keep getting an error that it's not there. It's a file that's constantly updated so I want to grab it at the source, which is GitHub.
COVID-19 Time Series is the third item on the page.
I tried the raw file URL, the CSV page URL, and GitHub consistently tells me that there is "no such file or directory".
Here's my code:
require 'open-uri'
require 'csv'
covids = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv"
puts File.exist?(covids)
keys = CSV.open(covids, &:readline)
How can I reference this file? I know I am logged in, but Ruby should be able to see those file paths.
A URL is not a file, so you can't open it with CSV.open neither use it in a File.exist? call. I see you've already included open-uri in your code, so the quick way to solve this would be to download the file using open and pass it to CSV.open:
keys = CSV.open(open(covids), &:readline)
puts keys
The selected answer has some problems:
OpenURI's open is deprecated. Instead use URI.open:
pry(main)> open(covids)
(pry):9: warning: calling URI.open via Kernel#open is deprecated, call URI.open directly or use URI#open
CSV.open, while it works, is counter to the signature of the method, which wants a filename, not an IO object. It's conceivable that relying on CSV.open to continue taking an IO object will break in the future if they fix this behavior.
Instead, the CSV documentation's first example recommends:
csv = CSV.new(string_or_io, **options)
# Reading: IO object should be open for read
csv.read # => array of rows
# or
csv.each do |row|
# ...
end
...
foreach is the form of each I'd use because that fits my brain better, YMMV:
CSV.foreach(URI.open(covids))
as a starting point. Here's an example looking at the first record in the file:
require 'open-uri'
require 'csv'
covids = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv"
CSV.foreach(URI.open(covids)).first
# => ["Province/State",
# "Country/Region",
# "Lat",
# "Long",
# "1/22/20",
# "1/23/20",
# "1/24/20",
# "1/25/20",
# "1/26/20",
# "1/27/20",
# "1/28/20",
# "1/29/20",
# "1/30/20",
# "1/31/20",
# "2/1/20",
# "2/2/20",
# "2/3/20",
# "2/4/20",
# "2/5/20",
# "2/6/20",
# "2/7/20",
# "2/8/20",
# "2/9/20",
# "2/10/20",
# "2/11/20",
# "2/12/20",
# "2/13/20",
# "2/14/20",
# "2/15/20",
# "2/16/20",
# "2/17/20",
# "2/18/20",
# "2/19/20",
# "2/20/20",
# "2/21/20",
# "2/22/20",
# "2/23/20",
# "2/24/20",
# "2/25/20",
# "2/26/20",
# "2/27/20",
# "2/28/20",
# "2/29/20",
# "3/1/20",
# "3/2/20",
# "3/3/20",
# "3/4/20",
# "3/5/20",
# "3/6/20",
# "3/7/20",
# "3/8/20",
# "3/9/20",
# "3/10/20"]
While OpenURI is convenient, it's not the most full-featured of the Ruby HTTP clients. I'd recommend working with something at the top of the Ruby HTTP client list.
Also, write your code carefully so you don't beat your network or GitHub's following best practices for using HEAD requests to check the last time the file was updated; Don't repeatedly GET (download) a file that hasn't been updated because that's just bad network manners.
At this point you'd be prepared to parse the file, saving the information to disk or reusing it for something else. I'd recommend dumping it into a database for easier reuse using something like Sequel, which makes it trivial to build and access the schema and data of SQLite writing to a disk-based DB, or PostgreSQL or MySQL for more full-featured DBMs.

Is there a .gemrc.local or equivalent?

Like many people I created a dotfiles repo and am trying extract bits that are not private into their respective dotfiles. I generally have a .whatever.local file loaded if it's present which might contain information I don't want checked into a repository. Rubygems use ~/.gemrc file, but I can't see a way to extract private information out of it into separate file. Does anyone know how this might be done?
In particular I'd like to have the list of sources external to the .gemrc file.
I do not see an equivalent to .local as per v2.4.6 (a recent, but not last version).
The source code of RubyGems states something relevant for what you want to achieve, though. For example, in src/ruby-2.3.0/lib/rubygems/config_file.rb:
##
# Gem::ConfigFile RubyGems options and gem command options from gemrc.
#
# gemrc is a YAML file that uses strings to match gem command arguments and
# symbols to match RubyGems options.
#
# Gem command arguments use a String key that matches the command name and
# +:sources+:: Sets Gem::sources
# +:verbose+:: See #verbose
#
# gemrc files may exist in various locations and are read and merged in
# the following order:
#
# - system wide (/etc/gemrc)
# - per user (~/.gemrc)
# - per environment (gemrc files listed in the GEMRC environment variable)
So you could use the GEMRC environment variable to load extra, private files as well.

Reading in variables from a file in Ruby

Is there a way to read in a file of environment variables?
In bash I have a file env.sh that I can use
env.sh
foo="bar"
bash file
set -a
source env.sh
This would allow me to just use foo as if I had delcared it in the ruby script.
Also is it there a way to make sure that this file is unreadable so that passwords could be stored in this file?
It sounds like you should provide a file example for the user/admin to modify for their personal environment, and then populate the environment from that, while avoiding, perhaps, having that file with the sensitive information in a repository. Note: per file security is going to be addressed by where the file is located and your operating system, and server software.
If this is the case, then you can provide a file that holds a template of the kind of things that you would require from the administrator/user of the program you are configuring.
Ruby has the ENV constant that acts like a Hash and holds the environment of the shell you are using.
As an example, there is a file called environment.rb.sample that gets shared with anyone, publicly. It has instructions and holds the template that users can modify freely, with instructions to copy the file to environment.rb. The sample file looks like this:
# environment.rb.sample
# Copy this file to environment.rb and change the name and password to your credentials
ENV['temp_user_name'] = 'Foo Bar'
ENV['temp_password'] = 'Dazz Kezz
The file is then copied to this, perhaps:
# environment.rb
ENV['temp_user_name'] = 'Joe Admin'
ENV['temp_password'] = 'Super Secure Password'
The file that loads this and uses it is just a Ruby file that is freely modified by the user/administrator of the software, and looks like this and is also shared publicly.
# load_environment
require './environment'
puts ENV['temp_user_name']
puts ENV['temp_password']
This loads the file and uses the ENV that is a globally scoped constant for the application.
The file permissions are then managed by the user/administrator of the system and secured like any other sensitive information on their system. The sensitive file should also be listed in the repository's ignore mechanism. It should never be made public.
Yes, there is, and if for some bizzare, arcane reason you must use it, it's eval:
WARNING: Never use this on a user-supplied file
And, unless you have a very, very specific need, don't use it in production code.
eval(File.read("name_of_var_file"), binding)
If what you're really trying to do is write a configuration file, use YAML. A file like this:
config.yaml:
foo: "bar"
Can be accessed like this:
require 'yaml'
conf = YAML.loads(File.read("config.yaml"))
conf['foo'] #=> 'bar'
This is secure and manageable, not to mention standard practice.
As for making the file inaccessible, that is an operating system level problem that can't be solved without information on the environment, OS, setup, etc.
The purpose of a local variable is to be used temporally within a method definition or a block. Using it outside of such environments, particularly across files defeats the purpose of it. You should not need to do it, and Ruby does not have a simple way to do it.
If you are using variables correctly, and want to share variables between files, that should be other types of variables such as instance, class, or global variables. Or, for the purpose of setting environments, you should be using constants. Among them, global variables and constants can be written in a file, loaded in a different file, and be used.
file-a.rb
$foo = 1
FOO = 2
file-b.rb
load "file-a.rb"
$foo # => 1
FOO # => 2
As for instance and class variables, they belong to a class or an instance of it, so they should be defined in such environment. And you can reopen the same class within a different file, and load it in another file.
file-a.rb
class Bar
##foo = 1
def initialize; #foo = 2 end
end
file-b.rb
load "file-a.rb"
Bar.class_variable_get("##foo") # => 1
Bar.new.instance_variable_get("#foo") # => 2

Resources