Automated the google forms to pdf generation process. Using pdflatex command (external program).

Only the download automation has to be done. > look at FileSystemWatcher for automatically detecting downloads
This commit is contained in:
Douwe Ravers
2022-12-24 15:18:20 +01:00
parent bc576e433a
commit abf812c6e9
99 changed files with 2224 additions and 428 deletions

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>

View File

@@ -0,0 +1,47 @@
using System.Linq;
namespace Proostenkrant.NET
{
internal static class ArticleGenerator
{
internal static string GenerateArticle(string[][] rows)
{
var text = string.Empty;
foreach (var row in rows)
{
var writers = row[1].Split(',').Select(w => w.Trim()).ToArray();
var title = row[2];
var date = row[3];
var mainText = row[4];
var imageName = row[5];
text += GenerateHeader(writers[0], title, date);
text += GenerateBody(writers, date, mainText, imageName);
text += "\n\n";
}
return text;
}
static string GenerateHeader(string writer, string title, string date)
{
var text = string.Empty;
text += "\\headline{" + title + "}\r\n";
text += "\\byline{" + date + "}{" + writer + "}\r\n";
return text;
}
static string GenerateBody(string[] writers, string date, string mainText, string imageName)
{
var text = string.Empty;
if (writers.Length == 2)
text += "\\showTwoWriters{Images/ProfilePictures/" + writers[0] + ".jpg}{" + writers[0] + "}{Images/ProfilePictures/" + writers[1] + ".jpg}{" + writers[1] + "}\r\n";
else
text += "\\showOneWriter{Images/ProfilePictures/" + writers[0] + ".jpg}{" + writers[0] + "}\r\n";
text += "\\par " + mainText + "\r\n";
text += "\\showInlineImage{Images/Articles/" + imageName + ".jpg}{" + imageName + "}\r\n";
return text;
}
}
}

View File

@@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
namespace Proostenkrant.NET
{
internal static class GoogleFormsReader
{
const string tsvDataUrl = "https://docs.google.com/spreadsheets/d/e/2PACX-1vRfxfdT8f4MQjXWmZylnXCGl14T0x5mxNw3W1Xd8GrZfPivjcqRGIvmb2YoAf77M00PrGPSJ6Zo-hRs/pub?output=tsv";
const string downloadURL = "https://drive.google.com/uc?export=download&id=FILEID";
public static string[][] GetData()
{
var tsvData = GetTsvData();
var data = ConvertData(tsvData);
var imageNames = LoadImages(data);
return data.Select((v, i) =>
{
v[5] = imageNames[i];
return v;
}).ToArray();
}
static string GetTsvData()
{
var client = new HttpClient();
var downloadTsvTask = client.GetStringAsync(tsvDataUrl);
downloadTsvTask.Wait();
return downloadTsvTask.Result;
}
static string[][] ConvertData(string tsvData)
{
// Split rows
var tsvRows = tsvData.Split('\r').Where(v => v.Length > 0);
// Split values
var rows = tsvRows.Select(r => r.Split('\t').Where(v => v.Length > 0));
// Remove header rows
rows = rows.ToList().GetRange(2, rows.Count() - 2);
return rows.Select(r => r.ToArray()).ToArray();
}
static string[] LoadImages(string[][] data)
{
var names = new List<string>();
foreach (var row in data)
{
var name = Regex.Replace(row[2], string.Concat(Path.GetInvalidFileNameChars()), string.Empty, RegexOptions.Compiled);
name = name.Replace(":", "");
names.Add(name);
var filename = Program.c_articleImagesPath + $"/{name}.jpg";
if (File.Exists(filename)) continue;
var id = row[5].Replace("https://drive.google.com/open?id=", string.Empty);
var url = downloadURL.Replace("FILEID", id);
Console.WriteLine("Downloading images using the browser...");
var process = Process.Start(url);
process.WaitForExit();
Console.Write("Drag image here : ");
var path = Console.ReadLine().Trim('\"');
File.Copy(path, filename);
}
return names.ToArray();
}
}
}

View File

@@ -0,0 +1,28 @@
using System.Diagnostics;
using System.IO;
namespace Proostenkrant.NET
{
internal static class LatexCompiler
{
internal static void Compile(string text)
{
File.WriteAllText(Program.c_articlePath, text);
GeneratePdf();
}
static void GeneratePdf()
{
var processInfo = new ProcessStartInfo("cmd.exe", "/c pdflatex " + Program.c_mainPath);
processInfo.WorkingDirectory = Program.c_latexPath;
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = true;
var process = Process.Start(processInfo);
process.WaitForExit();
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
namespace Proostenkrant.NET
{
public class Program
{
internal const string c_latexPath = "../Latex";
internal const string c_mainPath = c_latexPath + "/Main.tex";
internal const string c_articlePath = c_latexPath + "/Articles.tex";
internal const string c_imagesPath = c_latexPath + "/Images";
internal const string c_articleImagesPath = c_imagesPath + "/Articles";
static void Main(string[] args)
{
var rows = GoogleFormsReader.GetData();
var text = ArticleGenerator.GenerateArticle(rows);
LatexCompiler.Compile(text);
Console.WriteLine("Done!");
Console.ReadLine();
}
}
}

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F984715F-2FCA-4A9A-B8A9-020D482FD394}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Proostenkrant.NET</RootNamespace>
<AssemblyName>Proostenkrant.NET</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Build\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>
</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ArticleGenerator.cs" />
<Compile Include="GoogleFormsReader.cs" />
<Compile Include="LatexCompiler.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Proostenkrant.NET")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Proostenkrant.NET")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f984715f-2fca-4a9a-b8a9-020d482fd394")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]

View File

@@ -0,0 +1 @@
36ee40575dbbea1fa5315cbc1554d56b6770af33

View File

@@ -0,0 +1,8 @@
C:\Users\douwe\Projects\Proostenkrant.NET\Build\Proostenkrant.NET.exe.config
C:\Users\douwe\Projects\Proostenkrant.NET\Build\Proostenkrant.NET.exe
C:\Users\douwe\Projects\Proostenkrant.NET\Build\Proostenkrant.NET.pdb
C:\Users\douwe\Projects\Proostenkrant.NET\Proostenkrant.NET\obj\Debug\Proostenkrant.NET.csproj.AssemblyReference.cache
C:\Users\douwe\Projects\Proostenkrant.NET\Proostenkrant.NET\obj\Debug\Proostenkrant.NET.csproj.SuggestedBindingRedirects.cache
C:\Users\douwe\Projects\Proostenkrant.NET\Proostenkrant.NET\obj\Debug\Proostenkrant.NET.csproj.CoreCompileInputs.cache
C:\Users\douwe\Projects\Proostenkrant.NET\Proostenkrant.NET\obj\Debug\Proostenkrant.NET.exe
C:\Users\douwe\Projects\Proostenkrant.NET\Proostenkrant.NET\obj\Debug\Proostenkrant.NET.pdb

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]