Files
av-parser/src/AvParser.UI/Localization/Strings.resx
T
Leonid PershinandClaude Opus 5 44fb0d3a5f Gate network parsers on a working proxy and remember what worked
The pool now warms up from what the previous run learned instead of starting
cold every launch. Startup probes the remembered proxies first, stops as soon
as ProxyMinimumLive of them answer, and writes the survivors to
proxies.state.json after the warm-up and again on shutdown. Only proxies that
ever answered are stored: the feed republishes a few thousand dead addresses
every five minutes, and "was dead an hour ago" says almost nothing.

Remembered state is a hint, not a verdict. A restored proxy sorts first in the
warm-up queue but is not counted live until it answers in this session -
otherwise a launch a week later would report live proxies it had never spoken
to, the warm-up would skip the very entries it exists to re-check, and the
parser gate would open on week-old evidence.

That gate is the other half: a parser declaring RequiresNetwork will not run
while the pool has nothing live. The Parse page disables the run button and
shows a banner that leads to the Proxies page. Parsers that work on pasted text
are never gated - they have nothing to route, and blocking them would make the
app useless whenever the public lists are down. Two new settings cover the
escape hatch and the target: "allow network parsers without a proxy" and how
many live proxies to find at startup.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 19:11:51 +03:00

512 lines
19 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Shell.ToggleNavigation" xml:space="preserve">
<value>Toggle navigation</value>
</data>
<data name="Shell.Back" xml:space="preserve">
<value>Back</value>
</data>
<data name="Shell.ToggleTheme" xml:space="preserve">
<value>Switch light / dark</value>
</data>
<data name="Page.Dashboard" xml:space="preserve">
<value>Dashboard</value>
</data>
<data name="Page.Parse" xml:space="preserve">
<value>Parse</value>
</data>
<data name="Page.Proxies" xml:space="preserve">
<value>Proxies</value>
</data>
<data name="Page.Settings" xml:space="preserve">
<value>Settings</value>
</data>
<data name="Page.About" xml:space="preserve">
<value>About</value>
</data>
<data name="Dashboard.Tagline" xml:space="preserve">
<value>A parser shell with an adaptive layout. Drag the window narrower to watch the navigation collapse to an icon rail and then to an overlay drawer.</value>
</data>
<data name="Dashboard.RegisteredParsers" xml:space="preserve">
<value>Registered parsers</value>
</data>
<data name="Dashboard.GetStarted" xml:space="preserve">
<value>Get started</value>
</data>
<data name="Dashboard.OpenParser" xml:space="preserve">
<value>Open the parser</value>
</data>
<data name="Dashboard.DataDirectory" xml:space="preserve">
<value>DATA DIRECTORY</value>
</data>
<data name="Parse.Parser" xml:space="preserve">
<value>PARSER</value>
</data>
<data name="Parse.Actions" xml:space="preserve">
<value>ACTIONS</value>
</data>
<data name="Parse.Run" xml:space="preserve">
<value>Parse</value>
</data>
<data name="Parse.Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Parse.Sample" xml:space="preserve">
<value>Sample</value>
</data>
<data name="Parse.SampleTip" xml:space="preserve">
<value>Fill the input with a small example</value>
</data>
<data name="Parse.LargeSample" xml:space="preserve">
<value>50k rows</value>
</data>
<data name="Parse.LargeSampleTip" xml:space="preserve">
<value>Generate 50 000 rows, so progress and cancellation are observable</value>
</data>
<data name="Parse.ClearTip" xml:space="preserve">
<value>Clear input and results</value>
</data>
<data name="Parse.Input" xml:space="preserve">
<value>INPUT</value>
</data>
<data name="Parse.InputPlaceholder" xml:space="preserve">
<value>Paste text here, or press Sample</value>
</data>
<data name="Parse.Records" xml:space="preserve">
<value>RECORDS</value>
</data>
<data name="Parse.Errors" xml:space="preserve">
<value>ERRORS</value>
</data>
<data name="Parse.Count.Records.One" xml:space="preserve">
<value>{0} record</value>
</data>
<data name="Parse.Count.Records.Few" xml:space="preserve">
<value>{0} records</value>
</data>
<data name="Parse.Count.Records.Many" xml:space="preserve">
<value>{0} records</value>
</data>
<data name="Parse.Count.Errors.One" xml:space="preserve">
<value>{0} error</value>
</data>
<data name="Parse.Count.Errors.Few" xml:space="preserve">
<value>{0} errors</value>
</data>
<data name="Parse.Count.Errors.Many" xml:space="preserve">
<value>{0} errors</value>
</data>
<data name="Parse.Status.Done" xml:space="preserve">
<value>Parsed {0} in {1} ms.</value>
</data>
<data name="Parse.Status.Cancelled" xml:space="preserve">
<value>Cancelled after {0} in {1} ms.</value>
</data>
<data name="Parse.Status.WithErrors" xml:space="preserve">
<value>{0}, {1}.</value>
</data>
<data name="Parse.Status.Truncated" xml:space="preserve">
<value>Showing the first {0} only.</value>
</data>
<data name="Parse.Status.Failed" xml:space="preserve">
<value>Parse failed: {0}</value>
</data>
<data name="Proxies.Pool" xml:space="preserve">
<value>POOL</value>
</data>
<data name="Proxies.Refresh" xml:space="preserve">
<value>Refresh</value>
</data>
<data name="Proxies.RefreshTip" xml:space="preserve">
<value>Reload every source</value>
</data>
<data name="Proxies.CheckAll" xml:space="preserve">
<value>Check all</value>
</data>
<data name="Proxies.CheckAllTip" xml:space="preserve">
<value>Probe every proxy in the pool</value>
</data>
<data name="Proxies.Search" xml:space="preserve">
<value>SEARCH</value>
</data>
<data name="Proxies.SearchPlaceholder" xml:space="preserve">
<value>address or country</value>
</data>
<data name="Proxies.Protocol" xml:space="preserve">
<value>PROTOCOL</value>
</data>
<data name="Proxies.StatusColumn" xml:space="preserve">
<value>STATUS</value>
</data>
<data name="Proxies.Alive" xml:space="preserve">
<value>alive</value>
</data>
<data name="Proxies.Total" xml:space="preserve">
<value>total</value>
</data>
<data name="Proxies.Matched" xml:space="preserve">
<value>matched</value>
</data>
<data name="Proxies.ListHeader" xml:space="preserve">
<value>PROXIES</value>
</data>
<data name="Proxies.CustomHeader" xml:space="preserve">
<value>CUSTOM PROXIES</value>
</data>
<data name="Proxies.Add" xml:space="preserve">
<value>Add</value>
</data>
<data name="Proxies.Remove" xml:space="preserve">
<value>Remove</value>
</data>
<data name="Proxies.RemoveTip" xml:space="preserve">
<value>Remove the selected custom proxy</value>
</data>
<data name="Proxies.ClearTip" xml:space="preserve">
<value>Clear the custom list</value>
</data>
<data name="Proxies.CustomHint" xml:space="preserve">
<value>One per line. scheme://host:port, or host:port for plain HTTP. user:pass@ is supported.</value>
</data>
<data name="Proxies.Health.Alive" xml:space="preserve">
<value>alive</value>
</data>
<data name="Proxies.Health.Dead" xml:space="preserve">
<value>dead</value>
</data>
<data name="Proxies.Health.Unchecked" xml:space="preserve">
<value>unchecked</value>
</data>
<data name="Proxies.Source.Feed" xml:space="preserve">
<value>feed</value>
</data>
<data name="Proxies.Source.Custom" xml:space="preserve">
<value>custom</value>
</data>
<data name="Proxies.Count.Proxies.One" xml:space="preserve">
<value>{0} proxy</value>
</data>
<data name="Proxies.Count.Proxies.Few" xml:space="preserve">
<value>{0} proxies</value>
</data>
<data name="Proxies.Count.Proxies.Many" xml:space="preserve">
<value>{0} proxies</value>
</data>
<data name="Proxies.Status.PoolHolds" xml:space="preserve">
<value>Pool holds {0}.</value>
</data>
<data name="Proxies.Status.Nothing" xml:space="preserve">
<value>Nothing to add.</value>
</data>
<data name="Proxies.Status.Added" xml:space="preserve">
<value>Added {0} of {1}.</value>
</data>
<data name="Proxies.Status.Rejected" xml:space="preserve">
<value>Could not parse: {0}</value>
</data>
<data name="Proxies.Status.RejectedMore" xml:space="preserve">
<value>and {0} more</value>
</data>
<data name="Proxies.Status.Answered" xml:space="preserve">
<value>{0} of {1} answered.</value>
</data>
<data name="Proxies.Status.CheckCancelled" xml:space="preserve">
<value>Check cancelled.</value>
</data>
<data name="Proxies.Status.Removed" xml:space="preserve">
<value>Removed {0}.</value>
</data>
<data name="Proxies.Status.Cleared" xml:space="preserve">
<value>Custom list cleared.</value>
</data>
<data name="Proxies.Status.Failed" xml:space="preserve">
<value>Failed: {0}</value>
</data>
<data name="Settings.Appearance" xml:space="preserve">
<value>Appearance</value>
</data>
<data name="Settings.Theme" xml:space="preserve">
<value>THEME</value>
</data>
<data name="Settings.ThemeHint" xml:space="preserve">
<value>System follows the operating system's light/dark setting.</value>
</data>
<data name="Settings.Language" xml:space="preserve">
<value>LANGUAGE</value>
</data>
<data name="Settings.LanguageHint" xml:space="preserve">
<value>Applies immediately — no restart needed.</value>
</data>
<data name="Settings.Diagnostics" xml:space="preserve">
<value>Diagnostics</value>
</data>
<data name="Settings.LogLevel" xml:space="preserve">
<value>MINIMUM LOG LEVEL</value>
</data>
<data name="Settings.LogLevelHint" xml:space="preserve">
<value>Applies immediately — no restart needed.</value>
</data>
<data name="Settings.SettingsFile" xml:space="preserve">
<value>SETTINGS FILE</value>
</data>
<data name="Settings.LogDirectory" xml:space="preserve">
<value>LOG DIRECTORY</value>
</data>
<data name="Settings.Proxies" xml:space="preserve">
<value>Proxies</value>
</data>
<data name="Settings.Rotation" xml:space="preserve">
<value>ROTATION</value>
</data>
<data name="Settings.LivenessCheck" xml:space="preserve">
<value>LIVENESS CHECK</value>
</data>
<data name="Settings.UseFeed" xml:space="preserve">
<value>Use the public proxifly feed</value>
</data>
<data name="Settings.ProbeUrl" xml:space="preserve">
<value>PROBE URL</value>
</data>
<data name="Settings.ProbeUrlHint" xml:space="preserve">
<value>Plain HTTP by default: requiring TLS would fail every proxy that cannot do CONNECT, not just the dead ones.</value>
</data>
<data name="Settings.ProbeTimeout" xml:space="preserve">
<value>PROBE TIMEOUT (SEC)</value>
</data>
<data name="Settings.ProbeConcurrency" xml:space="preserve">
<value>PARALLEL PROBES</value>
</data>
<data name="Settings.Rotation.Sticky" xml:space="preserve">
<value>One proxy per session, replaced only when it fails. Keeps site sessions intact.</value>
</data>
<data name="Settings.Rotation.RoundRobin" xml:space="preserve">
<value>A different proxy on every request. Spreads rate limits, but breaks session cookies.</value>
</data>
<data name="Settings.Rotation.WeightedRandom" xml:space="preserve">
<value>Random, weighted by feed score and how often the proxy has actually worked here.</value>
</data>
<data name="Settings.HealthCheck.Pool" xml:space="preserve">
<value>Probe the whole pool up front, in parallel. One sweep, then no per-request delay.</value>
</data>
<data name="Settings.HealthCheck.Lazy" xml:space="preserve">
<value>Probe each proxy as it is handed out. No sweep, but every acquisition pays a round trip.</value>
</data>
<data name="Settings.Breakpoints" xml:space="preserve">
<value>Layout breakpoints</value>
</data>
<data name="Settings.BreakpointsHint" xml:space="preserve">
<value>Window widths at which the navigation changes shape. Resize the window to see it happen.</value>
</data>
<data name="Settings.Breakpoint.Compact" xml:space="preserve">
<value>COMPACT</value>
</data>
<data name="Settings.Breakpoint.Medium" xml:space="preserve">
<value>MEDIUM</value>
</data>
<data name="Settings.Breakpoint.Expanded" xml:space="preserve">
<value>EXPANDED</value>
</data>
<data name="Settings.Breakpoint.CompactHint" xml:space="preserve">
<value>below {0} px — overlay drawer</value>
</data>
<data name="Settings.Breakpoint.MediumHint" xml:space="preserve">
<value>{0} {1} px — icon rail</value>
</data>
<data name="Settings.Breakpoint.ExpandedHint" xml:space="preserve">
<value>from {0} px — full sidebar</value>
</data>
<data name="About.BuiltWith" xml:space="preserve">
<value>Built with</value>
</data>
<data name="About.OnDisk" xml:space="preserve">
<value>On disk</value>
</data>
<data name="About.Data" xml:space="preserve">
<value>DATA</value>
</data>
<data name="About.Logs" xml:space="preserve">
<value>LOGS</value>
</data>
<data name="About.Component.Dotnet" xml:space="preserve">
<value>.NET</value>
</data>
<data name="About.Component.Os" xml:space="preserve">
<value>Operating system</value>
</data>
<data name="About.Component.Avalonia" xml:space="preserve">
<value>Avalonia</value>
</data>
<data name="About.Component.ReactiveUI" xml:space="preserve">
<value>ReactiveUI</value>
</data>
<data name="About.Component.Semi" xml:space="preserve">
<value>Semi.Avalonia</value>
</data>
<data name="About.Component.NotLoaded" xml:space="preserve">
<value>not loaded</value>
</data>
<data name="Enum.AppTheme.System" xml:space="preserve">
<value>System</value>
</data>
<data name="Enum.AppTheme.Light" xml:space="preserve">
<value>Light</value>
</data>
<data name="Enum.AppTheme.Dark" xml:space="preserve">
<value>Dark</value>
</data>
<data name="Enum.AppLanguage.System" xml:space="preserve">
<value>System</value>
</data>
<data name="Enum.AppLanguage.English" xml:space="preserve">
<value>English</value>
</data>
<data name="Enum.AppLanguage.Russian" xml:space="preserve">
<value>Русский</value>
</data>
<data name="Enum.ProxyRotation.Sticky" xml:space="preserve">
<value>Sticky</value>
</data>
<data name="Enum.ProxyRotation.RoundRobin" xml:space="preserve">
<value>Round-robin</value>
</data>
<data name="Enum.ProxyRotation.WeightedRandom" xml:space="preserve">
<value>Weighted random</value>
</data>
<data name="Enum.ProxyHealthCheck.Pool" xml:space="preserve">
<value>Whole pool</value>
</data>
<data name="Enum.ProxyHealthCheck.Lazy" xml:space="preserve">
<value>On hand-out</value>
</data>
<data name="Enum.ProxyProtocolFilter.All" xml:space="preserve">
<value>All</value>
</data>
<data name="Enum.ProxyProtocolFilter.Http" xml:space="preserve">
<value>HTTP</value>
</data>
<data name="Enum.ProxyProtocolFilter.Https" xml:space="preserve">
<value>HTTPS</value>
</data>
<data name="Enum.ProxyProtocolFilter.Socks4" xml:space="preserve">
<value>SOCKS4</value>
</data>
<data name="Enum.ProxyProtocolFilter.Socks5" xml:space="preserve">
<value>SOCKS5</value>
</data>
<data name="Enum.ProxyHealthFilter.All" xml:space="preserve">
<value>All</value>
</data>
<data name="Enum.ProxyHealthFilter.Alive" xml:space="preserve">
<value>Alive</value>
</data>
<data name="Enum.ProxyHealthFilter.Dead" xml:space="preserve">
<value>Dead</value>
</data>
<data name="Enum.ProxyHealthFilter.Unchecked" xml:space="preserve">
<value>Unchecked</value>
</data>
<data name="Parser.delimited.Name" xml:space="preserve">
<value>Delimited text</value>
</data>
<data name="Parser.delimited.Description" xml:space="preserve">
<value>First non-empty line is the header. Rows are split on the delimiter that dominates it (, ; tab |).</value>
</data>
<data name="Parser.key-value.Name" xml:space="preserve">
<value>Key / value pairs</value>
</data>
<data name="Parser.key-value.Description" xml:space="preserve">
<value>One pair per line, separated by '=' or ':'. Lines starting with '#' are comments.</value>
</data>
<data name="Parse.Error.FieldCount" xml:space="preserve">
<value>Expected {0} field(s) but found {1}.</value>
</data>
<data name="Parse.Error.NoHeader" xml:space="preserve">
<value>Input contains no header row.</value>
</data>
<data name="Parse.Error.NoSeparator" xml:space="preserve">
<value>No '=' or ':' separator found.</value>
</data>
<data name="Parse.Error.EmptyKey" xml:space="preserve">
<value>Key is empty.</value>
</data>
<data name="Proxies.Status.Ready" xml:space="preserve">
<value>{0} in the pool, {1} live.</value>
</data>
<data name="Parse.ProxyRequired" xml:space="preserve">
<value>This parser needs a working proxy, and none is available. Check the proxy list, or allow direct connections in settings.</value>
</data>
<data name="Parse.GoToProxies" xml:space="preserve">
<value>Open proxies</value>
</data>
<data name="Settings.AllowDirect" xml:space="preserve">
<value>Allow network parsers to run without a proxy</value>
</data>
<data name="Settings.AllowDirectHint" xml:space="preserve">
<value>When off, a parser that fetches anything refuses to start until at least one proxy answers. Parsers that only read pasted text are never blocked.</value>
</data>
<data name="Settings.MinimumLive" xml:space="preserve">
<value>LIVE PROXIES TO FIND AT STARTUP</value>
</data>
<data name="Settings.MinimumLiveHint" xml:space="preserve">
<value>Startup checks the ones that worked last time first and stops as soon as it has this many. Raising it makes the first launch slower.</value>
</data>
</root>